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
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);
|
|
}
|