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