Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

982 lines
32 KiB

/* *************************************************************************
** INTEL Corporation Proprietary Information
**
** This listing is supplied under the terms of a license
** agreement with INTEL Corporation and may not be copied
** nor disclosed except in accordance with the terms of
** that agreement.
**
** Copyright (c) 1996 Intel Corporation.
** All Rights Reserved.
**
** *************************************************************************
*/
//
////////////////////////////////////////////////////////////////////////////
//
// $Author: mbodart $
// $Date: 17 Mar 1997 08:22:08 $
// $Archive: S:\h26x\src\enc\exbase.cpv $
// $Header: S:\h26x\src\enc\exbase.cpv 1.73 17 Mar 1997 08:22:08 mbodart $
// $Log: S:\h26x\src\enc\exbase.cpv $
//
// Rev 1.73 17 Mar 1997 08:22:08 mbodart
// Minor fixes.
//
// Rev 1.72 11 Mar 1997 13:46:46 JMCVEIGH
// Allow input = 320x240 and output = 320x240 for YUV12. This is
// for snapshot mode.
//
// Rev 1.71 10 Mar 1997 17:34:34 MDUDA
// Put in a check for 9-bit YUV12 and adjusted the internal compress
// structure instead of the input bitmap header info.
//
// Rev 1.70 10 Mar 1997 10:41:20 MDUDA
// Treating inconsistent format/bitwidth as a debug warning. Changing
// bit count to match format.
//
// Rev 1.69 07 Mar 1997 16:00:32 JMCVEIGH
// Added checks for non-NULL lpInst before getting H263PlusState.
// Two separate "suggestions" for image sizes if input size is not
// supported in GetFormat.
//
// Rev 1.68 07 Mar 1997 11:55:44 JMCVEIGH
// Moved query in GetFormat to after we have filled out the output
// format. This is because some apps. will ask for the format and
// then use the returned data, regardless if there was an error.
// Silly apps!
//
// Rev 1.67 07 Mar 1997 09:53:08 mbodart
// Added a call to _clearfp() in the Compress exception handler, so that
// the exception will not reoccur in the caller's code.
//
// Rev 1.66 06 Mar 1997 15:39:26 KLILLEVO
//
// CompressQuery now checks for input/output formats regardless
// of configuration status. Also put in trace support for lparam1 and lparam2.
//
// Rev 1.65 22 Jan 1997 12:17:14 MDUDA
//
// Put in more checking for H263+ option in CompressQuery
// and CompressBegin.
//
// Rev 1.64 22 Jan 1997 08:11:22 JMCVEIGH
// Backward compatibility with crop/stretch for 160x120 and 240x180
// in CompressGetFormat(). Do old way unless we have received the
// H263Plus custom message.
//
// Rev 1.63 13 Jan 1997 10:52:14 JMCVEIGH
//
// Added NULL pointer checks in all functions that interface with
// application.
//
// Rev 1.62 09 Jan 1997 13:50:50 MDUDA
// Removed some _CODEC_STATS stuff.
//
// Rev 1.61 06 Jan 1997 17:42:30 JMCVEIGH
// If H263Plus message is not sent, encoder only supports standard
// frame sizes (sub-QCIF, QCIF, or CIF along with special cases),
// as before.
//
// Rev 1.60 30 Dec 1996 19:57:04 MDUDA
// Making sure that input formats agree with the bit count field.
//
// Rev 1.59 20 Dec 1996 15:25:28 MDUDA
// Fixed problem where YUV12 was enabled for crop and stretch.
// This feature is only allowed for RGB, YVU9 and YUY2.
//
// Rev 1.58 16 Dec 1996 13:36:08 MDUDA
//
// Modified Compress Instance info for input color convertors.
//
// Rev 1.57 11 Dec 1996 16:01:20 MBODART
// In Compress, catch any exceptions and return an error code. This gives
// upstream active movie filters a chance to recover gracefully.
//
// Rev 1.56 09 Dec 1996 17:59:36 JMCVEIGH
// Added support for arbitrary frame size support.
// 4 <= width <= 352, 4 <= height <= 288, both multiples of 4.
// Normally, application will pass identical (arbitrary) frame
// sizes in lParam1 and lParam2 of CompressBegin(). If
// cropping/stretching desired to convert to standard frame sizes,
// application should pass the desired output size in lParam2 and
// the input size in lParam1.
//
// Rev 1.55 09 Dec 1996 09:50:12 MDUDA
//
// Allowing 240x180 and 160x120 (crop and stretch) for YUY2.
// Modified _CODEC_STATS stuff.
//
// Rev 1.54 07 Nov 1996 14:45:16 RHAZRA
// Added buffer size adjustment to H.261 CompressGetSize() function
//
// Rev 1.53 31 Oct 1996 22:33:32 BECHOLS
// Decided buffer arbitration must be done in cxq_main.cpp for RTP.
//
// Rev 1.52 31 Oct 1996 21:55:50 BECHOLS
// Added fudge factor for RTP waiting for Raj to decide what he wants to do.
//
// Rev 1.51 31 Oct 1996 10:05:46 KLILLEVO
// changed from DBOUT to DbgLog
//
// Rev 1.50 18 Oct 1996 14:35:46 MDUDA
//
// Separated CompressGetSize and CompressQuery for H261 and H263 cases.
//
// Rev 1.49 11 Oct 1996 16:05:16 MDUDA
//
// Added initial _CODEC_STATS stuff.
//
// Rev 1.48 16 Sep 1996 16:50:52 CZHU
// Return larger size for GetCompressedSize when RTP is enabled.
//
// Rev 1.47 13 Aug 1996 10:36:46 MDUDA
//
// Now allowing RGB4 input format.
//
// Rev 1.46 09 Aug 1996 09:43:30 MDUDA
// Now allowing RGB16 format on input. This is generated by the color Quick Ca
//
// Rev 1.45 02 Aug 1996 13:45:58 MDUDA
//
// Went back to previous version that allows RGB8 and RGB24 in
// 240x180 and 160x120 frames.
//
// Rev 1.44 01 Aug 1996 11:54:58 BECHOLS
// Cut & Paste Error.
//
// Rev 1.43 01 Aug 1996 11:20:28 BECHOLS
// Fixed handling of RGB 24 bit stuff so that it doesn't allow sizes other
// than QCIF, SQCIF, or CIF. I broke this earlier when I added the RGB 8
// bit support. ...
//
// Rev 1.42 22 Jul 1996 13:31:16 BECHOLS
//
// Added code to allow a CLUT8 input providing that the input resolutions
// are either 240x180 or 160x120.
//
// Rev 1.41 11 Jul 1996 15:43:58 MDUDA
// Added support for YVU9 240 x 180 and 160 x 120 for H263 only.
// We now produce subQCIF for 160x120 and QCIF for 240x180.
//
// Rev 1.40 05 Jun 1996 10:57:54 AKASAI
// Added #ifndef H261 in CompressQuery to make sure that H.261 will
// only support FCIF and QCIF input image sizes. All other input sizes
// should return ICERR_BADFORMAT.
//
// Rev 1.39 30 May 1996 17:02:34 RHAZRA
// Added SQCIF support for H.263 in CompressGetSize()
//
// Rev 1.38 06 May 1996 12:47:40 BECHOLS
// Changed the structure element to unBytesPerSecond.
//
// Rev 1.37 06 May 1996 00:09:44 BECHOLS
// Changed the handling of the CompressFramesInfo message to get DataRate
// from the configuration data if the configuration has the data, and
// we haven't received a CompressBegin message yet.
//
// Rev 1.36 23 Apr 1996 16:51:20 KLILLEVO
// moved paranthesis to fix format check in CompressQuery()
//
// Rev 1.35 18 Apr 1996 16:07:10 RHAZRA
// Fixed CompressQuery to keep compiler happy for the non-MICROSOFT version
//
// Rev 1.34 18 Apr 1996 15:57:46 BECHOLS
// RAJ- Changed the query logic to correctly filter the allowable resolutions
// for compression.
//
// Rev 1.33 12 Apr 1996 14:15:40 RHAZRA
// Added paranthesis in CompressGetSize() to make the ifdef case work
//
// Rev 1.32 12 Apr 1996 13:31:02 RHAZRA
// Added SQCIF support in CompressGetSize() with #ifdef SUPPORT_SQCIF;
// changed CompressGetSize() to return 0 if the input format is not
// supported.
//
// Rev 1.31 10 Apr 1996 16:53:08 RHAZRA
// Added a error return in CompressGetSize() to keep complier smiling...
//
// Rev 1.30 10 Apr 1996 16:39:56 RHAZRA
// Added a check for the 320x240 size in CompressGetSize() function;
// added a ifndef to disable certain sizes and compression formats.
//
// Rev 1.29 04 Apr 1996 13:35:00 RHAZRA
// Changed CompressGetSize() to return spec-compliant buffer sizes.
//
// Rev 1.28 03 Apr 1996 08:39:52 SCDAY
// Added H261 specific code to CompressGetSize to limit buffer size
// as defined in H261 spec
//
// Rev 1.27 21 Feb 1996 11:43:12 SCDAY
// cleaned up compiler build warning by changing conversion frlDataRate to (U3
//
// Rev 1.26 15 Feb 1996 16:03:36 RHAZRA
//
// Added a check for NULL lpInst pointer in CompressGetFormat()
//
// Rev 1.25 02 Feb 1996 18:53:46 TRGARDOS
// Changed code to read frame rate from Compressor Instance
// instead of the hack from Quality field.
//
// Rev 1.24 26 Jan 1996 09:35:32 TRGARDOS
// Added #ifndef H261 for 160x120,320x240 support.
//
// Rev 1.23 04 Jan 1996 18:36:54 TRGARDOS
// Added code to permit 320x240 input and then set a boolean
// bIs320x240.
//
// Rev 1.22 27 Dec 1995 15:32:50 RMCKENZX
// Added copyright notice
//
///////////////////////////////////////////////////////////////////////////
#include "precomp.h"
#ifdef YUV9FROMFILE
PAVIFILE paviFile;
PAVISTREAM paviStream;
U8 huge * glpTmp;
HGLOBAL hgMem;
#endif
;////////////////////////////////////////////////////////////////////////////
;// Function: DWORD PASCAL CompressGetFormat(LPCODINST, LPBITMAPINFOHEADER, LPBITMAPINFOHEADER);
;//
;// Description: Added header. This function returns a format that
;// we can deliver back to the caller.
;//
;// History: 05/11/94 -BEN-
;////////////////////////////////////////////////////////////////////////////
DWORD PASCAL CompressGetFormat(LPCODINST lpInst, LPBITMAPINFOHEADER lParam1, LPBITMAPINFOHEADER lParam2)
{
DWORD dwQuery;
// lpInst == NULL is OK
// this is what you get on ICOpen(...,ICMODE_QUERY)
#if 0
if (lpInst == NULL) {
DBOUT("CompressGetFormat: got a NULL lpInst pointer");
return ((DWORD) ICERR_ERROR);
}
#endif
if(dwQuery = CompressQuery(lpInst, lParam1, NULL)) {
DBOUT("encbase.c :: CompressGetFormat :: ICERR_BADFORMAT")
return(dwQuery);
}
if(lParam2 == NULL) {
// he just want me to return the output buffer size.
return ((DWORD)sizeof(BITMAPINFOHEADER));
}
// Check pointer
if (!lParam1)
return ICERR_ERROR;
// give him back what he passed with our stuff in it
#ifndef WIN32
(void)_fmemcpy(lParam2, lParam1,sizeof(BITMAPINFOHEADER));
#else
(void)memcpy(lParam2, lParam1,sizeof(BITMAPINFOHEADER));
#endif
lParam2->biBitCount = 24;
lParam2->biCompression = FOURCC_H263;
#if defined(H263P)
BOOL bH263PlusState = FALSE;
if (lpInst)
CustomGetH263PlusState(lpInst, (DWORD FAR *)&bH263PlusState);
if (!bH263PlusState) {
// For backward compatibility, make sure the crop and stretch cases are covered.
if ( (lParam1->biCompression == FOURCC_YVU9) ||
(lParam1->biCompression == FOURCC_YUY2) ||
(lParam1->biCompression == FOURCC_UYVY) ||
(lParam1->biCompression == FOURCC_YUV12) ||
(lParam1->biCompression == FOURCC_IYUV) ||
(lParam1->biCompression == BI_RGB) )
{
if ( (lParam1->biWidth == 240) && (lParam1->biHeight == 180) )
{
lParam2->biWidth = 176;
lParam2->biHeight = 144;
}
if ( (lParam1->biWidth == 160) && (lParam1->biHeight == 120) )
{
lParam2->biWidth = 128;
lParam2->biHeight = 96;
}
}
}
#else
if ( (lParam1->biCompression == FOURCC_YVU9) ||
(lParam1->biCompression == FOURCC_YUY2) ||
(lParam1->biCompression == FOURCC_UYVY) ||
(lParam1->biCompression == FOURCC_YUV12) ||
(lParam1->biCompression == FOURCC_IYUV) ||
(lParam1->biCompression == BI_RGB) )
{
if ( (lParam1->biWidth == 240) && (lParam1->biHeight == 180) )
{
lParam2->biWidth = 176;
lParam2->biHeight = 144;
}
if ( (lParam1->biWidth == 160) && (lParam1->biHeight == 120) )
{
lParam2->biWidth = 128;
lParam2->biHeight = 96;
}
}
else
{
lParam2->biWidth = MOD4(lParam1->biWidth);
lParam2->biHeight = MOD4(lParam1->biHeight);
}
#endif
lParam2->biClrUsed = 0;
lParam2->biClrImportant = 0;
lParam2->biPlanes = 1;
lParam2->biSizeImage = CompressGetSize(lpInst, lParam1, lParam2);
return(ICERR_OK);
}
;////////////////////////////////////////////////////////////////////////////
;// Function: DWORD PASCAL CompressGetSize(LPCODINST, LPBITMAPINFOHEADER, LPBITMAPINFOHEADER);
;//
;// Description: Added header. This function returns the maximum
;// size that a compressed buffer can be. This size is
;// guaranteed in encoder design.
;//
;// History: 05/11/94 -BEN-
;////////////////////////////////////////////////////////////////////////////
#if defined(H261)
DWORD PASCAL CompressGetSize(LPCODINST lpInst, LPBITMAPINFOHEADER lParam1, LPBITMAPINFOHEADER lParam2)
{
// RH: For QCIF and CIF, the maximum buffer sizes for 261 & 263 are identical.
DWORD dwRet = 0;
DWORD dwExtSize=0;
if ( ((lParam1->biWidth == 176) && (lParam1->biHeight == 144)) ||
((lParam1->biWidth == 240) && (lParam1->biHeight == 180)) ||
((lParam1->biWidth == 160) && (lParam1->biHeight == 120)) ) {
dwRet = 8192L;
} else
if (((lParam1->biWidth == 352) && (lParam1->biHeight == 288)) ||
((lParam1->biWidth == 320) && (lParam1->biHeight == 240))) {
dwRet = 32768L;
}
else // unsupported frame size; should not happen
{
DBOUT("CompressGetSize:ICERR_BADIMAGESIZE");
dwRet = 0;
}
// Adjust the buffer size for RTP. Note that this adjustment will be performed
// only if the codec has been told previously to use RTP and the RTP-related
// information has been initialized. Therefore, the current (11/7) AM interface
// will not take advantage of this routine.
#if 0
if (dwRet && lpInst && lpInst->Configuration.bRTPHeader && lpInst->Configuration.bInitialized)
{
dwRet += H261EstimateRTPOverhead(lpInst, lParam1);
}
#endif
return dwRet;
}
#else
/* H.263 case */
DWORD PASCAL CompressGetSize(LPCODINST lpInst, LPBITMAPINFOHEADER lParam1, LPBITMAPINFOHEADER lParam2)
{
// RH: For QCIF and CIF, the maximum buffer sizes for 261 & 263 are identical.
DWORD dwRet = 0;
DWORD dwExtSize=0;
if (lParam1 == NULL)
{
// We will use a size of zero to indicate an error for CompressGetSize
dwRet = 0;
return dwRet;
}
#ifndef H263P
if (((lParam1->biWidth == 128) && (lParam1->biHeight == 96)) ||
((lParam1->biWidth == 176) && (lParam1->biHeight == 144)) ||
((lParam1->biWidth == 240) && (lParam1->biHeight == 180)) ||
((lParam1->biWidth == 160) && (lParam1->biHeight == 120))) {
dwRet = 8192L;
} else
if (((lParam1->biWidth == 352) && (lParam1->biHeight == 288)) ||
((lParam1->biWidth == 320) && (lParam1->biHeight == 240))) {
dwRet = 32768L;
}
else // unsupported frame size; should not happen
{
DBOUT("CompressGetSize:ICERR_BADIMAGESIZE");
dwRet = 0;
}
#else
// H.263+
U32 unPaddedWidth;
U32 unPaddedHeight;
U32 unSourceFormatSize;
// Base buffer size on frame dimensions padded to multiples of 16
if (lParam2 == NULL)
{
// In case an old application passed in a NULL pointer in lParam2,
// we use the input frame dimensions to calculate the format size
unPaddedWidth = (lParam1->biWidth + 0xf) & ~0xf;
unPaddedHeight = (lParam1->biHeight + 0xf) & ~0xf;
}
else
{
unPaddedWidth = (lParam2->biWidth + 0xf) & ~0xf;
unPaddedHeight = (lParam2->biHeight + 0xf) & ~0xf;
}
unSourceFormatSize = unPaddedWidth * unPaddedHeight;
// See Table 1/H.263, document LBC-96-358
if (unSourceFormatSize < 25348)
dwRet = 8192L;
else if (unSourceFormatSize < 101380)
dwRet = 32768L;
else if (unSourceFormatSize < 405508)
dwRet = 65536L;
else
dwRet = 131072L;
#endif
//adjust if RTP is enabled, based on information in Configuration
//Size calculated using DataRate, FrameRate in lpInst,
//and lpInst->Configuration.unPacketSize;
//Chad, 9/12/96
#if 0
if (dwRet && lpInst &&
lpInst->Configuration.bRTPHeader && lpInst->Configuration.bInitialized)
{
dwRet += getRTPBsInfoSize(lpInst);
}
#endif
return dwRet;
}
#endif
;////////////////////////////////////////////////////////////////////////////
;// Function: DWORD PASCAL CompressQuery(LPCODINST, LPBITMAPINFOHEADER, LPBITMAPINFOHEADER);
;//
;// Description:
;//
;// History: 05/11/94 -BEN-
;////////////////////////////////////////////////////////////////////////////
#if defined(H261)
DWORD PASCAL CompressQuery(LPCODINST lpInst, LPBITMAPINFOHEADER lParam1, LPBITMAPINFOHEADER lParam2)
{
// Check for good input format
if(NULL == lParam1)
{
DBOUT("ICERR_BADFORMAT")
return((DWORD)ICERR_BADFORMAT);
}
if( (lParam1->biCompression != BI_RGB) &&
(lParam1->biCompression != FOURCC_YVU9) &&
(lParam1->biCompression != FOURCC_YUV12) &&
(lParam1->biCompression != FOURCC_IYUV) &&
(lParam1->biCompression != FOURCC_UYVY) &&
(lParam1->biCompression != FOURCC_YUY2) )
{
DBOUT("ICERR_BADFORMAT")
return((DWORD)ICERR_BADFORMAT);
}
if( (lParam1->biCompression == BI_RGB) &&
( (lParam1->biBitCount != 24) &&
(lParam1->biBitCount != 16) &&
(lParam1->biBitCount != 8) &&
(lParam1->biBitCount != 4) ) )
{
DBOUT("ICERR_BADFORMAT")
return((DWORD)ICERR_BADFORMAT);
}
if(!
( ((lParam1->biWidth == 176) && (lParam1->biHeight == 144)) ||
((lParam1->biWidth == 352) && (lParam1->biHeight == 288))
#ifndef MICROSOFT
||
( ( (lParam1->biCompression == FOURCC_YVU9) ||
(lParam1->biCompression == FOURCC_YUY2) ||
(lParam1->biCompression == FOURCC_UYVY) ||
(lParam1->biCompression == FOURCC_YUV12) ||
(lParam1->biCompression == FOURCC_IYUV) ||
(lParam1->biCompression == BI_RGB) )
&& ((lParam1->biWidth == 160) && (lParam1->biHeight == 120)) )
||
( ( (lParam1->biCompression == FOURCC_YVU9) ||
(lParam1->biCompression == FOURCC_YUY2) ||
(lParam1->biCompression == FOURCC_UYVY) ||
(lParam1->biCompression == FOURCC_YUV12) ||
(lParam1->biCompression == FOURCC_IYUV) ||
(lParam1->biCompression == BI_RGB) )
&& ((lParam1->biWidth == 240) && (lParam1->biHeight == 180)) )
||
( ( (lParam1->biCompression == FOURCC_YUV12) || (lParam1->biCompression == FOURCC_IYUV) )
&& ((lParam1->biWidth == 320) && (lParam1->biHeight == 240)) )
#endif
))
{
DBOUT("ICERR_BADFORMAT")
return((DWORD)ICERR_BADFORMAT);
}
if( lParam1->biPlanes != 1 )
{
DBOUT("ICERR_BADFORMAT")
return((DWORD)ICERR_BADFORMAT);
}
if(0 == lParam2) // Checking input only
return(ICERR_OK);
// TODO: Do we want to check frame dimensions of output?
if( lParam2->biCompression != FOURCC_H263 )
{
DBOUT("ICERR_BADFORMAT")
return((DWORD)ICERR_BADFORMAT);
}
return(ICERR_OK);
}
#else
/* H.263 case */
DWORD PASCAL CompressQuery(LPCODINST lpInst, LPBITMAPINFOHEADER lParam1, LPBITMAPINFOHEADER lParam2)
{
#if defined(H263P)
BOOL bH263PlusState = FALSE;
if (lpInst)
CustomGetH263PlusState(lpInst, (DWORD FAR *)&bH263PlusState);
#endif
// Check for good input format
if(NULL == lParam1)
{
DBOUT("ICERR_BADFORMAT")
return((DWORD)ICERR_BADFORMAT);
}
if( (lParam1->biCompression != BI_RGB) &&
(lParam1->biCompression != FOURCC_YVU9) &&
(lParam1->biCompression != FOURCC_YUV12) &&
(lParam1->biCompression != FOURCC_IYUV) &&
(lParam1->biCompression != FOURCC_YUY2) )
{
DBOUT("ICERR_BADFORMAT")
return((DWORD)ICERR_BADFORMAT);
}
if( (lParam1->biCompression == BI_RGB) &&
( (lParam1->biBitCount != 24) &&
#ifdef H263P
(lParam1->biBitCount != 32) &&
#endif
(lParam1->biBitCount != 16) &&
(lParam1->biBitCount != 8) &&
(lParam1->biBitCount != 4) ) )
{
DBOUT("ICERR_BADFORMAT")
return((DWORD)ICERR_BADFORMAT);
}
#ifndef H263P
if(!
( ((lParam1->biWidth == 128) && (lParam1->biHeight == 96)) ||
((lParam1->biWidth == 176) && (lParam1->biHeight == 144)) ||
((lParam1->biWidth == 352) && (lParam1->biHeight == 288))
#ifndef MICROSOFT
||
( ( (lParam1->biCompression == FOURCC_YVU9) ||
(lParam1->biCompression == FOURCC_YUY2) ||
(lParam1->biCompression == BI_RGB) )
&& ((lParam1->biWidth == 160) && (lParam1->biHeight == 120)) )
||
( ( (lParam1->biCompression == FOURCC_YVU9) ||
(lParam1->biCompression == FOURCC_YUY2) ||
(lParam1->biCompression == BI_RGB) )
&& ((lParam1->biWidth == 240) && (lParam1->biHeight == 180)) )
||
( ( (lParam1->biCompression == FOURCC_YUV12) ||
(lParam1->biCompression == FOURCC_IYUV) )
&& ((lParam1->biWidth == 320) && (lParam1->biHeight == 240)) )
#endif
))
{
DBOUT("ICERR_BADFORMAT")
return((DWORD)ICERR_BADFORMAT);
}
#else
if (((FOURCC_YVU9 == lParam1->biCompression) && (9 != lParam1->biBitCount)) ||
((FOURCC_YUY2 == lParam1->biCompression) && (16 != lParam1->biBitCount)) ||
(((FOURCC_YUV12 == lParam1->biCompression) || (FOURCC_IYUV == lParam1->biCompression)) && (12 != lParam1->biBitCount)))
{
DBOUT("CompressQuery:Incorrect bit width (ICERR_BADFORMAT)");
return((DWORD)ICERR_BADFORMAT);
}
// The H263+ message indicates whether arbitrary frame
// sizes are to be supported. If arbitrary frames are needed,
// the H263+ message must be sent before the first call to
// CompressQuery.
if (bH263PlusState) {
if ((lParam1->biWidth & 0x3) || (lParam1->biHeight & 0x3) ||
(lParam1->biWidth < 4) || (lParam1->biWidth > 352) ||
(lParam1->biHeight < 4) || (lParam1->biHeight > 288)) {
DBOUT("CompressQuery:ICERR_BADFORMAT");
return((DWORD)ICERR_BADFORMAT);
}
} else {
if(!
( ((lParam1->biWidth == 128) && (lParam1->biHeight == 96)) ||
((lParam1->biWidth == 176) && (lParam1->biHeight == 144)) ||
((lParam1->biWidth == 352) && (lParam1->biHeight == 288)) ||
( ( (lParam1->biCompression == FOURCC_YVU9) ||
(lParam1->biCompression == FOURCC_YUY2) ||
(lParam1->biCompression == BI_RGB) )
&& ((lParam1->biWidth == 160) && (lParam1->biHeight == 120)) ) ||
( ( (lParam1->biCompression == FOURCC_YVU9) ||
(lParam1->biCompression == FOURCC_YUY2) ||
(lParam1->biCompression == BI_RGB) )
&& ((lParam1->biWidth == 240) && (lParam1->biHeight == 180)) ) ||
( ( (lParam1->biCompression == FOURCC_YUV12) || (lParam1->biCompression == FOURCC_IYUV))
&& ((lParam1->biWidth == 320) && (lParam1->biHeight == 240)) ) ))
{
DBOUT("CompressQuery:ICERR_BADFORMAT");
return((DWORD)ICERR_BADFORMAT);
}
}
#endif
if( lParam1->biPlanes != 1 )
{
DBOUT("ICERR_BADFORMAT")
return((DWORD)ICERR_BADFORMAT);
}
if(lParam2 == 0) // Checking input only
return(ICERR_OK);
// TODO: Do we want to check frame dimensions of output?
if( lParam2->biCompression != FOURCC_H263 )
{
DBOUT("ICERR_BADFORMAT")
return((DWORD)ICERR_BADFORMAT);
}
#if defined(H263P)
if (bH263PlusState) {
if ((lParam1->biWidth != lParam2->biWidth) ||
(lParam1->biHeight != lParam2->biHeight)) {
DBOUT("CompressQuery:ICERR_BADFORMAT");
return ((DWORD)ICERR_BADFORMAT);
}
} else {
if(!
(( ( ((lParam1->biWidth == 128) && (lParam1->biHeight == 96)) ||
((lParam1->biWidth == 176) && (lParam1->biHeight == 144)) ||
((lParam1->biWidth == 352) && (lParam1->biHeight == 288)) ) &&
(lParam1->biWidth == lParam2->biWidth) && (lParam1->biHeight == lParam2->biHeight) ) ||
(((lParam1->biCompression == FOURCC_YVU9) ||
(lParam1->biCompression == FOURCC_YUY2) ||
(lParam1->biCompression == BI_RGB)) &&
(((lParam1->biWidth == 160) && (lParam1->biHeight == 120)) &&
((lParam2->biWidth == 128) && (lParam2->biHeight == 96)))) ||
(((lParam1->biCompression == FOURCC_YVU9) ||
(lParam1->biCompression == FOURCC_YUY2) ||
(lParam1->biCompression == BI_RGB)) &&
(((lParam1->biWidth == 240) && (lParam1->biHeight == 180)) &&
((lParam2->biWidth == 176) && (lParam2->biHeight == 144)))) ||
(((lParam1->biCompression == FOURCC_YUV12) || (lParam1->biCompression == FOURCC_IYUV)) &&
(((lParam1->biWidth == 320) && (lParam1->biHeight == 240)) &&
((lParam2->biWidth == 320) && (lParam2->biHeight == 240)))) ) )
{
DBOUT("CompressQuery:ICERR_BADFORMAT");
return ((DWORD)ICERR_BADFORMAT);
}
}
#endif
return(ICERR_OK);
}
#endif
;////////////////////////////////////////////////////////////////////////////
;// Function: DWORD PASCAL CompressFramesInfo(LPCODINST, ICCOMPRESSFRAMES *);
;//
;// Description:
;//
;// History: 05/11/94 -BEN-
;////////////////////////////////////////////////////////////////////////////
DWORD PASCAL CompressFramesInfo(LPCODINST lpCompInst, ICCOMPRESSFRAMES *lParam1, int lParam2)
{
FX_ENTRY("CompressFramesInfo");
// Check to see if we are given a nonzero pointer.
if (lpCompInst == NULL)
{
ERRORMESSAGE(("%s: CompressFramesInfo called with NULL parameter - returning ICERR_BADFORMAT", _fx_));
return ((DWORD)ICERR_BADFORMAT);
}
// lParam2 should be the size of the structure.
if (lParam2 != sizeof(ICCOMPRESSFRAMES))
{
ERRORMESSAGE(("%s: wrong size of ICOMPRESSFRAMES structure", _fx_));
return ((DWORD)ICERR_BADFORMAT);
}
if (!lParam1 || (lParam1->dwScale == 0))
{
ERRORMESSAGE(("%s: dwScale is zero", _fx_));
return ((DWORD)ICERR_BADFORMAT);
}
lpCompInst->FrameRate = (float)lParam1->dwRate / (float)lParam1->dwScale;
lpCompInst->DataRate = (U32)lParam1->lDataRate;
DEBUGMSG(ZONE_BITRATE_CONTROL, ("%s: Setting frame rate at %ld.%ld fps and bitrate at %ld bps", _fx_, (DWORD)lpCompInst->FrameRate, (DWORD)((lpCompInst->FrameRate - (float)(DWORD)lpCompInst->FrameRate) * 100.0f), lpCompInst->DataRate * 8UL));
return ((DWORD)ICERR_OK);
}
;////////////////////////////////////////////////////////////////////////////
;// Function: BOOL bIsOkRes(LPCODINST);
;//
;// Description: This function checks whether the desired height and
;// width are possible.
;//
;// History: 05/11/94 -BEN-
;////////////////////////////////////////////////////////////////////////////
BOOL bIsOkRes(LPCODINST lpCompInst)
{
BOOL bRet;
// Check for NULL pointer
if (lpCompInst == NULL)
return 0;
bRet = lpCompInst->xres <= 352
&& lpCompInst->yres <= 288
&& lpCompInst->xres >= 4
&& lpCompInst->yres >= 4
&& (lpCompInst->xres & ~3) == lpCompInst->xres
&& (lpCompInst->yres & ~3) == lpCompInst->yres;
return(bRet);
}
;////////////////////////////////////////////////////////////////////////////
;// Function: DWORD PASCAL CompressBegin(LPCODINST, LPBITMAPINFOHEADER, LPBITMAPINFOHEADER);
;//
;// Description:
;//
;// History: 05/11/94 -BEN-
;////////////////////////////////////////////////////////////////////////////
DWORD PASCAL CompressBegin(
LPCODINST lpCompInst,
LPBITMAPINFOHEADER lParam1,
LPBITMAPINFOHEADER lParam2
)
{
DWORD dwQuery;
LRESULT retval;
#if defined(H263P)
BOOL bH263PlusState = FALSE;
if (lpCompInst)
CustomGetH263PlusState(lpCompInst, (DWORD FAR *)&bH263PlusState);
#endif
// Check input and output format.
if( (dwQuery = CompressQuery(lpCompInst, lParam1, lParam2)) != ICERR_OK)
return(dwQuery);
// Check instance pointer
if (!lpCompInst)
return ICERR_ERROR;
#ifdef H263P
lpCompInst->InputCompression = lParam1->biCompression;
lpCompInst->InputBitWidth = lParam1->biBitCount;
if (((FOURCC_YUV12 == lParam1->biCompression) || (FOURCC_IYUV == lParam1->biCompression)) && (9 == lParam1->biBitCount)) {
lpCompInst->InputBitWidth = 12;
}
if ( lParam2 && bH263PlusState)
{
// This is the "new" style for indicating if the input should
// be cropped/stretched to a standard frame size.
// Old applications may pass in NULL or junk for lparam2.
// New applications should pass a valid lParam2 that indicates
// the desired output frame size. Also, the H263Plus flag must
// be set in the configuration structure before calling CompressBegin()
lpCompInst->xres = (WORD)lParam2->biWidth;
lpCompInst->yres = (WORD)lParam2->biHeight;
} else
#endif // H263P
{
lpCompInst->xres = (WORD)lParam1->biWidth;
lpCompInst->yres = (WORD)lParam1->biHeight;
lpCompInst->Is160x120 = FALSE;
lpCompInst->Is240x180 = FALSE;
lpCompInst->Is320x240 = FALSE;
if ( (lParam1->biWidth == 160) && (lParam1->biHeight == 120) )
{
lpCompInst->xres = 128;
lpCompInst->yres = 96;
lpCompInst->Is160x120 = TRUE;
}
else if ( (lParam1->biWidth == 240) && (lParam1->biHeight == 180) )
{
lpCompInst->xres = 176;
lpCompInst->yres = 144;
lpCompInst->Is240x180 = TRUE;
}
else if ( (lParam1->biWidth == 320) && (lParam1->biHeight == 240) )
{
lpCompInst->xres = 352;
lpCompInst->yres = 288;
lpCompInst->Is320x240 = TRUE;
}
}
if(!bIsOkRes(lpCompInst))
return((DWORD)ICERR_BADIMAGESIZE);
// Set frame size.
if (lpCompInst->xres == 128 && lpCompInst->yres == 96)
lpCompInst->FrameSz = SQCIF;
else if (lpCompInst->xres == 176 && lpCompInst->yres == 144)
lpCompInst->FrameSz = QCIF;
else if (lpCompInst->xres == 352 && lpCompInst->yres == 288)
lpCompInst->FrameSz = CIF;
#ifdef H263P
else
lpCompInst->FrameSz = CUSTOM;
#else
else // unsupported frame size.
return (DWORD)ICERR_BADIMAGESIZE;
#endif
// Allocate and Initialize tables and memory that are specific to
// this instance.
#if defined(H263P)
retval = H263InitEncoderInstance(lParam1,lpCompInst);
#else
retval = H263InitEncoderInstance(lpCompInst);
#endif
return(retval);
}
;////////////////////////////////////////////////////////////////////////////
;// Function: DWORD PASCAL CompressEnd(LPCODINST);
;//
;// Description:
;//
;// History: 05/11/94 -BEN-
;////////////////////////////////////////////////////////////////////////////
DWORD PASCAL CompressEnd(LPCODINST lpInst)
{
LRESULT retval;
retval = H263TermEncoderInstance(lpInst);
return(retval);
}
;////////////////////////////////////////////////////////////////////////////
;// Function: DWORD PASCAL Compress(LPCODINST, ICCOMPRESS FAR *, DWORD);
;//
;// Description:
;//
;// History: 05/11/94 -BEN-
;////////////////////////////////////////////////////////////////////////////
DWORD PASCAL Compress(
LPCODINST lpInst, // ptr to Compressor instance information.
ICCOMPRESS FAR * lpCompInfo, // ptr to ICCOMPRESS structure.
DWORD dOutbufSize // size, in bytes, of the ICCOMPRESS structure.
)
{
DWORD dwRet;
// Check to see if we are given a NULL pointer.
if(lpInst == NULL || lpCompInfo == NULL)
{
DBOUT("Compress called with NULL parameter");;
return( (DWORD) ICERR_ERROR );
}
try
{
dwRet = H263Compress(lpInst, lpCompInfo);
}
catch (...)
{
// For a DEBUG build, display a message and pass the exception up.
// For a release build, stop the exception here and return an error
// code. This gives upstream code a chance to gracefully recover.
// We also need to clear the floating point control word, otherwise
// the upstream code may incur an exception the next time it tries
// a floating point operation (presuming this exception was due
// to a floating point problem).
#if defined(DEBUG) || defined(_DEBUG)
DBOUT("Exception during H263Compress!!!");
throw;
#else
_clearfp();
return (DWORD) ICERR_ERROR;
#endif
}
if (dwRet != ICERR_OK)
{
DBOUT("H263Compress Failed");
}
// now transfer the information.
lpCompInfo->lpbiOutput->biSize =sizeof(BITMAPINFOHEADER);
lpCompInfo->lpbiOutput->biCompression = FOURCC_H263;
lpCompInfo->lpbiOutput->biPlanes = 1;
lpCompInfo->lpbiOutput->biBitCount = 24;
lpCompInfo->lpbiOutput->biWidth = lpInst->xres;
lpCompInfo->lpbiOutput->biHeight = lpInst->yres;
lpCompInfo->lpbiOutput->biSizeImage = lpInst->CompressedSize;
lpCompInfo->lpbiOutput->biClrUsed = 0;
lpCompInfo->lpbiOutput->biClrImportant = 0;
// lpCompInfo->dwFlags is set inside the compressor.
// set the chunk idea if requested
if (lpCompInfo->lpckid)
{
*(lpCompInfo->lpckid) = TWOCC_H26X;
}
return(dwRet);
}