304 lines
9.7 KiB
C++
304 lines
9.7 KiB
C++
|
|
#include "precomp.h"
|
|
|
|
#define INTEL_PRO 1
|
|
|
|
#ifdef INTEL_PRO
|
|
#define WIDTH 176
|
|
#define HEIGHT 144
|
|
#define NUMBPP 24
|
|
#ifndef _ALPHA_
|
|
#define VIDEO_FORMAT VIDEO_FORMAT_MSH263
|
|
#else
|
|
#define VIDEO_FORMAT VIDEO_FORMAT_DECH263
|
|
#endif
|
|
#define SIZE_IMAGE 8192
|
|
#else
|
|
#define WIDTH 160
|
|
#define HEIGHT 120
|
|
#define NUMBPP 16
|
|
#define VIDEO_FORMAT VIDEO_FORMAT_BI_RGB
|
|
#define SIZE_IMAGE (WIDTHBYTES(WIDTH * NUMBPP) * HEIGHT)
|
|
#endif
|
|
#define NUMFPS 7
|
|
#define BITRATE (SIZE_IMAGE * NUMFPS)
|
|
|
|
VIDEOFORMATEX g_vfDefList[DVF_NumOfFormats] =
|
|
{
|
|
#if 1
|
|
#if 1
|
|
{
|
|
VIDEO_FORMAT, // dwFormatTag
|
|
NUMFPS, // nSamplesPerSec
|
|
BITRATE, // nAvgBytesPerSec
|
|
BITRATE, // nMinBytesPerSec
|
|
BITRATE, // nMaxBytesPerSec
|
|
SIZE_IMAGE,// nBlockAlign
|
|
NUMBPP, // wBitsPerSample
|
|
// Temporal fields
|
|
142857UL, // dwRequestMicroSecPerFrame
|
|
10UL, // dwPersentDropForError
|
|
NUMFPS, // dwNumVideoRequested
|
|
1UL, // dwSupportTSTradeOff
|
|
TRUE, // bLive
|
|
sizeof(VIDEOFORMATEX), // dwFormatSize
|
|
// Spatial fields (BITMAPINFOHEADER compatible)
|
|
{
|
|
sizeof(BITMAPINFOHEADER), // bih.biSize
|
|
WIDTH, // bih.biWidth
|
|
HEIGHT, // bih.biHeight
|
|
1, // bih.biPlanes
|
|
NUMBPP, // bih.biBitCount
|
|
VIDEO_FORMAT, // bih.biCompression
|
|
SIZE_IMAGE,// bih.biSizeImage
|
|
0, 0, // bih.bi(X,Y)PelsPerMeter
|
|
0, // bih.biClrUsed
|
|
0 // bih.biClrImportant
|
|
}
|
|
}
|
|
#else
|
|
{
|
|
VIDEO_FORMAT_BI_RGB, // dwFormatTag
|
|
NUMFPS, // nSamplesPerSec
|
|
BITRATE, // nAvgBytesPerSec
|
|
BITRATE, // nMinBytesPerSec
|
|
BITRATE, // nMaxBytesPerSec
|
|
WIDTHBYTES(WIDTH * NUMBPP) * HEIGHT,// nBlockAlign
|
|
NUMBPP, // wBitsPerSample
|
|
// Temporal fields
|
|
142857UL, // dwRequestMicroSecPerFrame
|
|
10UL, // dwPersentDropForError
|
|
NUMFPS, // dwNumVideoRequested
|
|
1UL, // dwSupportTSTradeOff
|
|
TRUE, // bLive
|
|
sizeof(VIDEOFORMATEX), // dwFormatSize
|
|
// Spatial fields (BITMAPINFOHEADER compatible)
|
|
{
|
|
sizeof(BITMAPINFOHEADER), // bih.biSize
|
|
WIDTH, // bih.biWidth
|
|
HEIGHT, // bih.biHeight
|
|
1, // bih.biPlanes
|
|
NUMBPP, // bih.biBitCount
|
|
VIDEO_FORMAT_BI_RGB, // bih.biCompression
|
|
WIDTHBYTES(WIDTH * NUMBPP) * HEIGHT,// bih.biSizeImage
|
|
0, 0, // bih.bi(X,Y)PelsPerMeter
|
|
0, // bih.biClrUsed
|
|
0 // bih.biClrImportant
|
|
}
|
|
}
|
|
#endif
|
|
#else
|
|
{
|
|
// Wave format compatibility fields
|
|
(WORD)0, 7UL, 9600UL, 9600UL, 9600UL, (DWORD)1, (WORD)4,
|
|
// Temporal fields
|
|
142857UL, 10UL, 2UL, 142857UL, TRUE, sizeof(VIDEOFORMATEX),
|
|
// Spatial fields (BITMAPINFOHEADER compatible)
|
|
sizeof(BITMAPINFOHEADER), WIDTH, HEIGHT, 1, 4, BI_RGB, (DWORD)WIDTHBYTES(WIDTH * 4) * HEIGHT, 0, 0, 16, 0
|
|
}
|
|
#endif
|
|
};
|
|
#if 0
|
|
// Color information fields (Array of 256 RGBQUAD)
|
|
0, 0, 0, 0, 255, 255, 255, 0, 238, 238, 238, 0, 221, 221, 221, 0, 204, 204, 204, 0,
|
|
187, 187, 187, 0, 170, 170, 170, 0, 153, 153, 153, 0, 136, 136, 136, 0, 119, 119, 119, 0,
|
|
102, 102, 102, 0, 85, 85, 85, 0, 68, 68, 68, 0, 51, 51, 51, 0, 34, 34, 34, 0, 17, 17, 17, 0
|
|
}
|
|
};
|
|
{ 0, 0, 0, 0}, {255, 255, 255, 0}, {238, 238, 238, 0}, {221, 221, 221, 0}, {204, 204, 204, 0},
|
|
{187, 187, 187, 0}, {170, 170, 170, 0}, {153, 153, 153, 0}, {136, 136, 136, 0}, {119, 119, 119, 0},
|
|
{102, 102, 102, 0}, { 85, 85, 85, 0}, { 68, 68, 68, 0}, { 51, 51, 51, 0}, { 34, 34, 34, 0}, { 17, 17, 17, 0}
|
|
#endif
|
|
|
|
VIDEOFORMATEX * GetDefFormat ( int idx )
|
|
{
|
|
return ((idx < DVF_NumOfFormats) ?
|
|
(VIDEOFORMATEX *) &g_vfDefList[idx] :
|
|
(VIDEOFORMATEX *) NULL);
|
|
}
|
|
|
|
// Move all this into VideoPacket... same for AudioPacket and utils.c
|
|
ULONG GetFormatSize ( PVOID pwf )
|
|
{
|
|
return (((VIDEOFORMATEX *) pwf)->dwFormatSize);
|
|
}
|
|
|
|
BOOL IsSameFormat ( PVOID pwf1, PVOID pwf2 )
|
|
{
|
|
UINT u1 = GetFormatSize (pwf1);
|
|
UINT u2 = GetFormatSize (pwf2);
|
|
BOOL fSame = FALSE;
|
|
VIDEOFORMATEX *pvfx1 = (VIDEOFORMATEX *)pwf1;
|
|
VIDEOFORMATEX *pvfx2 = (VIDEOFORMATEX *)pwf2;
|
|
|
|
// Only compare relevant fields
|
|
if (pvfx1->dwFormatTag != pvfx2->dwFormatTag)
|
|
return FALSE;
|
|
if (pvfx1->nSamplesPerSec != pvfx2->nSamplesPerSec)
|
|
return FALSE;
|
|
if (pvfx1->nAvgBytesPerSec != pvfx2->nAvgBytesPerSec)
|
|
return FALSE;
|
|
if (pvfx1->nMinBytesPerSec != pvfx2->nMinBytesPerSec)
|
|
return FALSE;
|
|
if (pvfx1->nMaxBytesPerSec != pvfx2->nMaxBytesPerSec)
|
|
return FALSE;
|
|
if (pvfx1->nBlockAlign != pvfx2->nBlockAlign)
|
|
return FALSE;
|
|
if (pvfx1->wBitsPerSample != pvfx2->wBitsPerSample)
|
|
return FALSE;
|
|
if (pvfx1->bih.biSize != pvfx2->bih.biSize)
|
|
return FALSE;
|
|
if (pvfx1->bih.biWidth != pvfx2->bih.biWidth)
|
|
return FALSE;
|
|
if (pvfx1->bih.biHeight != pvfx2->bih.biHeight)
|
|
return FALSE;
|
|
if (pvfx1->bih.biPlanes != pvfx2->bih.biPlanes)
|
|
return FALSE;
|
|
if (pvfx1->bih.biBitCount != pvfx2->bih.biBitCount)
|
|
return FALSE;
|
|
if (pvfx1->bih.biCompression != pvfx2->bih.biCompression)
|
|
return FALSE;
|
|
if (pvfx1->bih.biSizeImage != pvfx2->bih.biSizeImage)
|
|
return FALSE;
|
|
if (pvfx1->bih.biClrUsed != pvfx2->bih.biClrUsed)
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// Repeat previous frame. This is probably not necessary
|
|
// since it is already painted on screen
|
|
void CopyPreviousBuf (VIDEOFORMATEX *pwf, PBYTE pb, ULONG cb)
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
// similar to the above "IsSameFormat" call, but similifed to satisfy
|
|
// the needs of SendVideoStream::Configure
|
|
BOOL IsSimilarVidFormat(VIDEOFORMATEX *pvfx1, VIDEOFORMATEX *pvfx2)
|
|
{
|
|
// Only compare relevant fields
|
|
if (pvfx1->bih.biWidth != pvfx2->bih.biWidth)
|
|
return FALSE;
|
|
if (pvfx1->bih.biHeight != pvfx2->bih.biHeight)
|
|
return FALSE;
|
|
if (pvfx1->bih.biCompression != pvfx2->bih.biCompression)
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
int GetIFrameCaps(IStreamSignal *pStreamSignal)
|
|
{
|
|
HRESULT hr;
|
|
PCC_VENDORINFO pLocalVendorInfo, pRemoteVendorInfo;
|
|
int nStringLength20, nStringLength21, nStringLength211, nStringLengthTAPI;
|
|
int nStringLength21sp1;
|
|
bool bIsNetMeeting = false; // contains NetMeeting in the product string
|
|
char *szProductCompare=NULL;
|
|
char *szVersionCompare=NULL;
|
|
int nLengthProduct, nLengthVersion;
|
|
int nRet = IFRAMES_CAPS_3RDPARTY;
|
|
|
|
if (pStreamSignal == NULL)
|
|
{
|
|
return IFRAMES_CAPS_UNKNOWN;
|
|
}
|
|
|
|
hr = pStreamSignal->GetVersionInfo(&pLocalVendorInfo, &pRemoteVendorInfo);
|
|
|
|
if (FAILED(hr) || (NULL == pRemoteVendorInfo))
|
|
{
|
|
return IFRAMES_CAPS_UNKNOWN;
|
|
}
|
|
|
|
|
|
// make sure we are dealing with a Microsoft product
|
|
if ((pRemoteVendorInfo->bCountryCode != USA_H221_COUNTRY_CODE) ||
|
|
(pRemoteVendorInfo->wManufacturerCode != MICROSOFT_H_221_MFG_CODE) ||
|
|
(pRemoteVendorInfo->pProductNumber == NULL) ||
|
|
(pRemoteVendorInfo->pVersionNumber == NULL)
|
|
)
|
|
{
|
|
return IFRAMES_CAPS_3RDPARTY;
|
|
}
|
|
|
|
|
|
// strings aren't guaranteed to be NULL terminated
|
|
// so let's make a quick copy of them that so that we can
|
|
// do easy string comparisons
|
|
nLengthProduct = pRemoteVendorInfo->pProductNumber->wOctetStringLength;
|
|
nLengthVersion = pRemoteVendorInfo->pVersionNumber->wOctetStringLength;
|
|
|
|
szProductCompare = new char[nLengthProduct+1];
|
|
szVersionCompare = new char[nLengthVersion+1];
|
|
|
|
if ((szProductCompare == NULL) || (szVersionCompare == NULL))
|
|
{
|
|
return IFRAMES_CAPS_3RDPARTY;
|
|
}
|
|
|
|
ZeroMemory(szProductCompare, nLengthProduct+1);
|
|
ZeroMemory(szVersionCompare, nLengthVersion+1);
|
|
|
|
CopyMemory(szProductCompare, pRemoteVendorInfo->pProductNumber->pOctetString, nLengthProduct);
|
|
CopyMemory(szVersionCompare, pRemoteVendorInfo->pVersionNumber->pOctetString, nLengthVersion);
|
|
|
|
// a redundant check to make sure that it is indeed a Microsoft product
|
|
if (NULL == _StrStr(szProductCompare, H323_COMPANYNAME_STR))
|
|
{
|
|
return IFRAMES_CAPS_3RDPARTY;
|
|
}
|
|
|
|
|
|
// quick check to see if this is NetMeeting or something else
|
|
if (NULL != _StrStr(szProductCompare, H323_PRODUCTNAME_SHORT_STR))
|
|
{
|
|
bIsNetMeeting = true;
|
|
}
|
|
|
|
// filter out NetMeeting 2.x
|
|
if (bIsNetMeeting)
|
|
{
|
|
if (
|
|
(0 == lstrcmp(szVersionCompare, H323_20_PRODUCTRELEASE_STR)) ||
|
|
(0 == lstrcmp(szVersionCompare, H323_21_PRODUCTRELEASE_STR)) ||
|
|
(0 == lstrcmp(szVersionCompare, H323_211_PRODUCTRELEASE_STR)) ||
|
|
(0 == lstrcmp(szVersionCompare, H323_21_SP1_PRODUCTRELEASE_STR))
|
|
)
|
|
{
|
|
delete [] szVersionCompare;
|
|
delete [] szProductCompare;
|
|
return IFRAMES_CAPS_NM2;
|
|
}
|
|
}
|
|
|
|
|
|
if (bIsNetMeeting == false)
|
|
{
|
|
// filter out TAPI v3.0
|
|
// their version string is "Version 3.0", NetMeeting is "3.0"
|
|
if (0 == lstrcmp(szVersionCompare, H323_TAPI30_PRODUCTRELEASE_STR))
|
|
{
|
|
delete [] szVersionCompare;
|
|
delete [] szProductCompare;
|
|
return IFRAMES_CAPS_3RDPARTY;
|
|
}
|
|
|
|
// a Microsoft product that isn't TAPI 3.0 or NetMeeting ?
|
|
// assume compliance with the I-Frames stuff
|
|
DEBUGMSG (ZONE_IFRAME, ("Microsoft H.323 product that isn't NetMeeting !\r\n"));
|
|
DEBUGMSG (ZONE_IFRAME, ("Assuming that that remote knows about I-Frames!\r\n"));
|
|
}
|
|
|
|
delete [] szVersionCompare;
|
|
delete [] szProductCompare;
|
|
|
|
// must be NetMeeting 3.0, TAPI 3.1, or later
|
|
return IFRAMES_CAPS_NM3;
|
|
}
|