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