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