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.
 
 
 
 
 
 

429 lines
14 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) 1995 Intel Corporation.
** Copyright (c) 1996 Intel Corporation.
** All Rights Reserved.
**
** *************************************************************************
//
// e3rtp.cpp
//
// Description:
// This file is for RTP payload generation. See EPS for details.
//
// Routines:
// getRTPPacketSizeThreshold
// H263RTP_InitBsInfoStream
// H263RTP_ResetBsInfoStream
// H263RTPFindMVs
// H263RTP_UpdateBsInfo
// H263RTP_TermBsInfoStream
// H263RTP_AttachBsInfoStream
// IsIntraCoded
// H263RTP_GetMaxBsInfoStreamSize()
//
// -------------------------------------------------------------------------
//
// $Author: gmlim $
// $Date: 17 Apr 1997 16:54:02 $
// $Archive: S:\h26x\src\enc\e3rtp.cpv $
// $Header: S:\h26x\src\enc\e3rtp.cpv 1.14 17 Apr 1997 16:54:02 gmlim $
// $Log: S:\h26x\src\enc\e3rtp.cpv $
//
// Rev 1.14 17 Apr 1997 16:54:02 gmlim
// Added H263RTP_GetMaxBsInfoStreamSize().
//
// Rev 1.13 06 Mar 1997 16:06:26 gmlim
// Changed RTP to generate mode A packet at the beginning of a GOB.
//
// Rev 1.12 18 Feb 1997 15:33:06 CZHU
// Changed UpdateBSInfo() not to force packet at GOB all the time.
//
// Rev 1.11 07 Feb 1997 10:57:28 CZHU
// Added three entry in EC to remove static variable used in e3rtp.cpp
//
// Rev 1.10 24 Jan 1997 13:33:36 CZHU
//
// Stop generating more packets when internal buffer is to overflow.
//
// Rev 1.9 11 Dec 1996 10:38:24 gmlim
// Removed unused pBsInfoStream from H263RTP_AttachBsInfoStream().
//
// Rev 1.8 05 Dec 1996 17:01:08 GMLIM
// Changed the way RTP packetization was done to guarantee proper packet
// size. Created H263RTP_ResetBsInfoStream() and replaced two previous
// bitstream info update fucntions with H263RTP_UpdateBsInfo().
//
// Rev 1.7 06 Nov 1996 16:31:06 gmlim
// Removed H263ModeC def.s and did some cleanup.
//
// Rev 1.6 03 Nov 1996 18:44:42 gmlim
// Added support for mode c.
//
// Rev 1.5 24 Oct 1996 16:27:50 KLILLEVO
// changed from DBOUT to DbgLog
//
// Rev 1.4 25 Sep 1996 10:55:28 CZHU
// Added checking null pointers at allocation and before use.
//
// Rev 1.3 16 Sep 1996 16:50:48 CZHU
// changed RTP BS Init for smaller packet size
//
// Rev 1.2 29 Aug 1996 09:31:00 CZHU
// Added a function checking intra-GOB
//
// Rev 1.1 28 Apr 1996 20:09:04 BECHOLS
//
// Removed RTP_HEADER IFDEFs.
//
// Rev 1.0 22 Apr 1996 17:46:10 BECHOLS
// Initial revision.
//
// Rev 1.7 10 Apr 1996 13:33:04 CZHU
// Moved packet loss sim to c3rtp.cpp
//
// Rev 1.6 29 Mar 1996 13:37:42 CZHU
//
// Rev 1.5 01 Mar 1996 16:37:08 DBRUCKS
// change to use 3/4ths of packet size as the threshold
// change to make packet size a parameter
//
// Rev 1.4 23 Feb 1996 17:36:48 CZHU
//
// Rev 1.3 23 Feb 1996 16:18:28 CZHU
// integrate with build 29
//
// Rev 1.2 15 Feb 1996 12:00:42 CZHU
// Clean up
//
// Rev 1.1 14 Feb 1996 14:59:36 CZHU
// Support both mode A and mode B payload modes.
//
// Rev 1.0 12 Feb 1996 17:04:44 CZHU
// Initial revision.
//
// Rev 1.5 25 Jan 1996 16:14:34 CZHU
// name changes
//
// Rev 1.4 15 Dec 1995 13:06:46 CZHU
//
// Rev 1.3 11 Dec 1995 14:52:42 CZHU
// Added support for per MB packetization
//
// Rev 1.2 04 Dec 1995 16:50:26 CZHU
//
// Rev 1.1 01 Dec 1995 15:53:52 CZHU
// Included Init() and Term() functions.
//
// Rev 1.0 01 Dec 1995 15:31:02 CZHU
// Initial revision.
** *************************************************************************/
#include "precomp.h"
#ifdef TRACK_ALLOCATIONS
char gsz1[32];
#endif
static U32 uBitOffset_currPacket;
static U8 *pBitStream_currPacket;
static U8 *pBitStream_lastPacket;
// ---------------------------------------------------------------------------
// getRTPPacketSizeThreshold()
// Helper function to calculate the threshold of packet size
// for given maximum packet size and data rate
// ---------------------------------------------------------------------------
static U32 getRTPPacketSizeThreshold(U32 uRequested)
{
U32 uSize;
// uSize = uRequested * 90 / 100;
uSize = uRequested;
ASSERT(uSize);
return uSize;
}
// ---------------------------------------------------------------------------
// H263RTP_InitBsInfoStream()
// ---------------------------------------------------------------------------
I32 H263RTP_InitBsInfoStream(LPCODINST lpInst, T_H263EncoderCatalog *EC)
{
U32 uBsInfoSize = getRTPBsInfoSize(lpInst);
FX_ENTRY("H263RTP_InitBsInfoStream")
if (EC->hBsInfoStream != NULL)
{
HeapFree(GetProcessHeap(), NULL, EC->pBaseBsInfoStream);
#ifdef TRACK_ALLOCATIONS
// Track memory allocation
RemoveName((unsigned int)EC->pBaseBsInfoStream);
#endif
}
EC->pBaseBsInfoStream = HeapAlloc(GetProcessHeap(), NULL, uBsInfoSize);
if (EC->pBaseBsInfoStream == NULL)
{
lpInst->Configuration.bRTPHeader = FALSE;
return FALSE;
}
#ifdef TRACK_ALLOCATIONS
// Track memory allocation
wsprintf(gsz1, "E3RTP: %7ld Ln %5ld\0", uBsInfoSize, __LINE__);
AddName((unsigned int)EC->pBaseBsInfoStream, gsz1);
#endif
EC->hBsInfoStream = (void *) uBsInfoSize;
EC->uPacketSizeThreshold = getRTPPacketSizeThreshold(lpInst->Configuration.unPacketSize);
DEBUGMSG(ZONE_INIT, ("%s: BsInfoStream initialized\r\n", _fx_));
return TRUE;
}
// ---------------------------------------------------------------------------
// H263RTP_ResetBsInfoStream()
// ---------------------------------------------------------------------------
void H263RTP_ResetBsInfoStream(T_H263EncoderCatalog *EC)
{
FX_ENTRY("H263RTP_ResetBsInfoStream")
EC->pBsInfoStream = EC->pBaseBsInfoStream;
EC->uBase = 0;
EC->uNumOfPackets = 0;
uBitOffset_currPacket = 0;
pBitStream_currPacket = EC->PictureHeader.PB ? EC->pU8_BitStrCopy :
EC->pU8_BitStream;
pBitStream_lastPacket = pBitStream_currPacket;
DEBUGMSG(ZONE_ENCODE_RTP, ("%s: BsInfoStream reset\r\n", _fx_));
}
// ---------------------------------------------------------------------------
// H263RTPFindMVs()
// Find motion vector predictors for current MB and return in arraryMVs[]
// ---------------------------------------------------------------------------
U32 H263RTPFindMVs(
T_H263EncoderCatalog * EC,
T_MBlockActionStream * pMBlockAction,
U32 uMBA,
U32 uGOBN,
I8 arrayMVs[2]
)
{
if (!uMBA)
{
arrayMVs[0] = 0;
arrayMVs[1] = 0;
}
else // revisit for AP
{
arrayMVs[0] = pMBlockAction[-1].BlkY1.PHMV;
arrayMVs[1] = pMBlockAction[-1].BlkY1.PVMV;
}
return TRUE;
}
// ---------------------------------------------------------------------------
// H263RTP_UpdateBsInfo()
// This routine is called at the beginning of each MB to update the bitstream
// info buffer
// ---------------------------------------------------------------------------
I32 H263RTP_UpdateBsInfo(
T_H263EncoderCatalog *EC,
T_MBlockActionStream *pMBlockAction,
U32 uQuant,
U32 uMBA,
U32 uGOBN,
U8 *pBitStream,
U32 uBitOffset
)
{
U32 uNewBytes;
T_RTP_H263_BSINFO *pBsInfoStream;
I8 arrayMVs[2];
FX_ENTRY("H263RTP_UpdateBsInfo")
if (EC->pBsInfoStream == NULL) return FALSE;
if (uMBA)
{
if ((U32) (pBitStream - pBitStream_lastPacket) <
EC->uPacketSizeThreshold)
{
pBitStream_currPacket = pBitStream;
uBitOffset_currPacket = uBitOffset;
return TRUE;
}
pBsInfoStream = (T_RTP_H263_BSINFO *) EC->pBsInfoStream;
pBsInfoStream->u8Mode = EC->PictureHeader.PB ? RTP_H263_MODE_C :
RTP_H263_MODE_B;
pBsInfoStream->u8MBA = (U8) uMBA;
pBsInfoStream->u8Quant = (U8) uQuant;
pBsInfoStream->u8GOBN = (U8) uGOBN;
H263RTPFindMVs(EC, pMBlockAction, uMBA, uGOBN, arrayMVs);
pBsInfoStream->i8HMV1 = arrayMVs[0];
pBsInfoStream->i8VMV1 = arrayMVs[1];
}
else
{
pBsInfoStream = (T_RTP_H263_BSINFO *) EC->pBsInfoStream;
pBsInfoStream->u8Mode = RTP_H263_MODE_A;
pBsInfoStream->u8MBA = 0;
pBsInfoStream->u8Quant = 0;
pBsInfoStream->u8GOBN = (U8) uGOBN;
pBsInfoStream->i8HMV1 = 0;
pBsInfoStream->i8VMV1 = 0;
}
uNewBytes = (U32) (pBitStream_currPacket - pBitStream_lastPacket);
EC->uBase += uNewBytes;
pBsInfoStream->uBitOffset = uBitOffset_currPacket + (EC->uBase << 3);
pBsInfoStream->i8HMV2 = 0;
pBsInfoStream->i8VMV2 = 0;
pBsInfoStream->uFlags = 0;
DEBUGMSG(ZONE_ENCODE_RTP, ("%s: Flag=%d,Mode=%d,GOB=%d,MB=%d,Quant=%d,BitOffset=%d,pBitStream=%lx,LastPacketSz=%d B\r\n", _fx_, pBsInfoStream->uFlags, pBsInfoStream->u8Mode, pBsInfoStream->u8GOBN, pBsInfoStream->u8MBA, pBsInfoStream->u8Quant, pBsInfoStream->uBitOffset, (U32) pBitStream_currPacket, uNewBytes));
// update packet pointers
pBitStream_lastPacket = pBitStream_currPacket;
pBitStream_currPacket = pBitStream;
uBitOffset_currPacket = uBitOffset;
// create a new packet: update counter and pointer
EC->uNumOfPackets ++;
EC->pBsInfoStream = (void *) ++ pBsInfoStream;
ASSERT((DWORD) EC->hBsInfoStream >
(DWORD) EC->pBsInfoStream - (DWORD) EC->pBaseBsInfoStream);
return TRUE;
} // H263RTP_UpdateBsInfo()
// ---------------------------------------------------------------------------
// H263RTP_TermBsInfoStream()
// ---------------------------------------------------------------------------
void H263RTP_TermBsInfoStream(T_H263EncoderCatalog * EC)
{
FX_ENTRY("H263RTP_TermBsInfoStream")
DEBUGMSG(ZONE_INIT, ("%s: BsInfoStream freed\r\n", _fx_));
HeapFree(GetProcessHeap(), NULL, EC->pBaseBsInfoStream);
#ifdef TRACK_ALLOCATIONS
// Track memory allocation
RemoveName((unsigned int)EC->pBaseBsInfoStream);
#endif
EC->hBsInfoStream= NULL;
return;
}
// ---------------------------------------------------------------------------
// H263RTP_AttachBsInfoStream()
// ---------------------------------------------------------------------------
U32 H263RTP_AttachBsInfoStream(
T_H263EncoderCatalog * EC,
U8 *lpOutput,
U32 uSize
)
{
U32 uIncreasedSize;
U8 *lpAligned;
T_H263_RTP_BSINFO_TRAILER BsInfoTrailer;
// build bsinfo for the last packets
BsInfoTrailer.uVersion = H263_RTP_PAYLOAD_VERSION;
BsInfoTrailer.uFlags = 0;
BsInfoTrailer.uUniqueCode = H263_RTP_BS_START_CODE;
BsInfoTrailer.uCompressedSize = uSize;
BsInfoTrailer.uNumOfPackets = EC->uNumOfPackets;
BsInfoTrailer.u8Src = EC->FrameSz;
BsInfoTrailer.u8TR = EC->PictureHeader.TR;
if (EC->PictureHeader.PicCodType == INTRAPIC)
BsInfoTrailer.uFlags |= RTP_H26X_INTRA_CODED;
if (EC->PictureHeader.PB == ON)
{
BsInfoTrailer.u8TRB = EC->PictureHeader.TRB;
BsInfoTrailer.u8DBQ = EC->PictureHeader.DBQUANT;
BsInfoTrailer.uFlags |= RTP_H263_PB;
}
else
{
BsInfoTrailer.u8TRB = 0;
BsInfoTrailer.u8DBQ = 0;
}
if (EC->PictureHeader.AP == ON)
BsInfoTrailer.uFlags |= RTP_H263_AP;
if (EC->PictureHeader.SAC == ON)
BsInfoTrailer.uFlags |= RTP_H263_SAC;
// update size field for the last BsInfoTrailer
uIncreasedSize = EC->uNumOfPackets * sizeof(T_RTP_H263_BSINFO);
// copy extended BS info and trailer to the given output buffer
lpAligned = (U8 *) ((U32) (lpOutput + uSize + 3) & 0xfffffffc);
memcpy(lpAligned, EC->pBaseBsInfoStream, uIncreasedSize);
memcpy(lpAligned + uIncreasedSize, &BsInfoTrailer,
sizeof(T_H263_RTP_BSINFO_TRAILER));
return(uIncreasedSize + sizeof(T_H263_RTP_BSINFO_TRAILER)
+ (U32) (lpAligned - lpOutput - uSize));
}
// ---------------------------------------------------------------------------
// IsIntraCoded(EC, GOB)
// return TRUE if current GOB is intra coded.
// other wise FALSE;
// Chad for intra GOB
// ---------------------------------------------------------------------------
BOOL IsIntraCoded(T_H263EncoderCatalog * EC, U32 Gob)
{
U32 uGobMax, uGobMin;
if (EC->uNumberForcedIntraMBs)
{
// for those GOBs are forced intra
uGobMax = EC->uNextIntraMB / EC->NumMBPerRow;
uGobMin = uGobMax - EC->uNumberForcedIntraMBs / EC->NumMBPerRow;
if (Gob >= uGobMin && Gob < uGobMax)
return TRUE;
}
return FALSE;
}
// ---------------------------------------------------------------------------
// H263RTP_GetMaxBsInfoStreamSize()
// return max size of EBS with trailer + 3 allignment bytes - 4/16/97 Gim
// ---------------------------------------------------------------------------
U32 H263RTP_GetMaxBsInfoStreamSize(T_H263EncoderCatalog *EC)
{
return (EC->uNumOfPackets * sizeof(T_RTP_H263_BSINFO) +
sizeof(T_H263_RTP_BSINFO_TRAILER) + 3);
}