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.
444 lines
11 KiB
444 lines
11 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.
|
|
**
|
|
** *************************************************************************
|
|
// $Author: AGUPTA2 $
|
|
// $Date: 14 Apr 1997 16:58:54 $
|
|
// $Archive: S:\h26x\src\enc\e1rtp.cpv $
|
|
// $Header: S:\h26x\src\enc\e1rtp.cpv 1.10 14 Apr 1997 16:58:54 AGUPTA2 $
|
|
// $Log: S:\h26x\src\enc\e1rtp.cpv $
|
|
//
|
|
// Rev 1.10 14 Apr 1997 16:58:54 AGUPTA2
|
|
// Added a new function to return size of just the extended bit-stream (RTP pa
|
|
//
|
|
// Rev 1.9 21 Nov 1996 10:51:46 RHAZRA
|
|
// Changed the packet threshold to 80%
|
|
//
|
|
// Rev 1.8 18 Nov 1996 17:11:34 MBODART
|
|
// Replaced all debug message invocations with Active Movie's DbgLog.
|
|
//
|
|
// Rev 1.7 07 Nov 1996 14:43:46 RHAZRA
|
|
// Changed declaration of packet size threshold function.
|
|
//
|
|
// Rev 1.6 30 Sep 1996 08:50:06 RHAZRA
|
|
// Look for zero GOB number entry in Rewind operation.
|
|
//
|
|
// Rev 1.5 24 Sep 1996 13:48:46 RHAZRA
|
|
// Changed MBAP to be in the range 0-31 as demanded by the RTP spec.
|
|
//
|
|
// Rev 1.4 17 Sep 1996 21:59:44 RHAZRA
|
|
// Assigned GOB number to zero at GOB-level packet fragmentation to
|
|
// be consistent with the RTP spec.
|
|
//
|
|
// Rev 1.3 16 Sep 1996 09:31:14 RHAZRA
|
|
//
|
|
// Now return motion vectors in interger pel units as opposed to
|
|
// half pel units for interoperability.
|
|
//
|
|
// Rev 1.2 26 Aug 1996 10:11:44 RHAZRA
|
|
// Fixed a bug in RewindBSinfoStream function.
|
|
//
|
|
// Rev 1.1 23 Aug 1996 13:04:52 RHAZRA
|
|
// Added #ifdef RING0 ... #endif to avoid wsprintf and GlobaclAlloc
|
|
// problems in RING0
|
|
//
|
|
// Rev 1.0 21 Aug 1996 18:31:20 RHAZRA
|
|
// Initial revision.
|
|
//
|
|
// 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
|
|
// ean up
|
|
// 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.
|
|
*/
|
|
|
|
/*
|
|
* This file is for RTP payload generation. See EPS for details
|
|
*
|
|
*
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
/*
|
|
* Helper function to calculate the threshold of packet size
|
|
* for given maximum packet size and data rate
|
|
*/
|
|
|
|
|
|
U32 getRTPPacketSizeThreshold(U32 uRequested)
|
|
{ U32 uSize;
|
|
uSize = (uRequested * 85) / 100;
|
|
ASSERT(uSize);
|
|
return uSize;
|
|
}
|
|
|
|
I32 H261RTP_InitBsInfoStream(
|
|
T_H263EncoderCatalog * EC,
|
|
UINT unPacketSize)
|
|
{
|
|
U32 uBsInfoSize;
|
|
|
|
uBsInfoSize = EC->FrameHeight * EC->FrameWidth * 3 / 4 ;
|
|
uBsInfoSize = uBsInfoSize*sizeof(T_RTP_H261_BSINFO)/ DEFAULT_PACKET_SIZE;
|
|
EC->hBsInfoStream= GlobalAlloc(GHND, uBsInfoSize);
|
|
if ( EC->hBsInfoStream)
|
|
{
|
|
EC->pBaseBsInfoStream = (void *)GlobalLock(EC->hBsInfoStream);
|
|
EC->pBsInfoStream = EC->pBaseBsInfoStream;
|
|
EC->uBase = 0;
|
|
EC->uNumOfPackets=0;
|
|
EC->uPacketSizeThreshold = getRTPPacketSizeThreshold(unPacketSize);
|
|
|
|
}
|
|
else return FALSE;
|
|
|
|
#ifndef RING0
|
|
#ifdef _DEBUG
|
|
DBOUT("BsInfoStream initialized....\n");
|
|
#endif
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
|
|
/*
|
|
* H263RTPFindMVs
|
|
* Find motion vector predictors for current MB and return in arraryMVs[]
|
|
*
|
|
*/
|
|
|
|
U32 H261RTPFindMVs (
|
|
T_H263EncoderCatalog * EC,
|
|
T_MBlockActionStream * pMBlockAction,
|
|
//U32 uMBA,
|
|
//U32 uGOBN,
|
|
I8 arrayMVs[2],
|
|
UN unCurrentMB,
|
|
UN unLastCodedMB
|
|
)
|
|
{
|
|
if ( ((unCurrentMB - unLastCodedMB) != 1) || ((unCurrentMB % 11) == 0) )
|
|
{
|
|
arrayMVs[0]=0;
|
|
arrayMVs[1]=0;
|
|
|
|
}
|
|
else
|
|
{
|
|
arrayMVs[0]= pMBlockAction[-1].BlkY1.PHMV;
|
|
arrayMVs[1]= pMBlockAction[-1].BlkY1.PVMV;
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
/*
|
|
* This routine is called at the beginning of each MB
|
|
* to update the BitstreamInfoStream;
|
|
*
|
|
*/
|
|
|
|
I32 H261RTP_MBUpdateBsInfo (
|
|
T_H263EncoderCatalog * EC,
|
|
T_MBlockActionStream * pMBlockAction,
|
|
U32 uQuant,
|
|
U32 uMBAP,
|
|
U32 uGOBN,
|
|
U8 *pBitStream,
|
|
U32 uBitOffset,
|
|
UN unCurrentMB,
|
|
UN unLastCodedMB
|
|
)
|
|
{
|
|
U32 uNewBytes;
|
|
T_RTP_H261_BSINFO *pBsInfoStream ;
|
|
|
|
//compute the difference
|
|
uNewBytes = (U32)pBitStream - (U32)EC->pU8_BitStream - EC->uBase;
|
|
|
|
if ((uNewBytes < EC->uPacketSizeThreshold) ||
|
|
(unCurrentMB == 0) )
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
I8 arrayMVs[2];
|
|
ASSERT(unCurrentMB); //it should not happen on the first MB in a GOB
|
|
pBsInfoStream = (T_RTP_H261_BSINFO *)EC->pBsInfoStream;
|
|
EC->uBase += uNewBytes;
|
|
pBsInfoStream->uFlags = 0;
|
|
pBsInfoStream->uBitOffset = uBitOffset + EC->uBase*8; //next bit
|
|
|
|
//pBsInfoStream->u8MBA = (U8)(unLastCodedMB + 1);
|
|
pBsInfoStream->u8MBA = (U8)(unLastCodedMB);
|
|
|
|
|
|
if (!unCurrentMB)
|
|
pBsInfoStream->u8Quant = (U8)0; // this case should never be true
|
|
else
|
|
pBsInfoStream->u8Quant = (U8)uQuant;
|
|
|
|
pBsInfoStream->u8GOBN = (U8)uGOBN;
|
|
|
|
H261RTPFindMVs(EC, pMBlockAction,/* uMBAP, uGOBN,*/ arrayMVs, unCurrentMB,
|
|
unLastCodedMB);
|
|
|
|
pBsInfoStream->i8HMV = (arrayMVs[0]>>1);
|
|
pBsInfoStream->i8VMV = (arrayMVs[1]>>1);
|
|
|
|
}//end of if (size <packetSize)
|
|
|
|
#ifndef RING0
|
|
#ifdef _DEBUG
|
|
{ char msg[200];
|
|
|
|
wsprintf(msg, "uFlag =%d,BitOffset=%d, MBA=%d, uQuant=%d,GOBN=%d,pBitStream=%lx,PacketSize= %d B",
|
|
pBsInfoStream->uFlags,
|
|
pBsInfoStream->uBitOffset,
|
|
pBsInfoStream->u8MBA,
|
|
pBsInfoStream->u8Quant,
|
|
pBsInfoStream->u8GOBN,
|
|
(U32)pBitStream,
|
|
uNewBytes);
|
|
DBOUT(msg);
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
EC->pBsInfoStream = (void *) ++pBsInfoStream; //create a new packet
|
|
EC->uNumOfPackets++;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*
|
|
* This Routine is called every GOB except GOB 1 to build a
|
|
* packet
|
|
*
|
|
*/
|
|
|
|
I32 H261RTP_GOBUpdateBsInfo (
|
|
T_H263EncoderCatalog * EC,
|
|
U32 uGOBN,
|
|
U8 *pBitStream,
|
|
U32 uBitOffset
|
|
)
|
|
{
|
|
U32 uNewBytes;
|
|
T_RTP_H261_BSINFO *pBsInfoStream ;
|
|
|
|
//compute the difference
|
|
uNewBytes = (U32)pBitStream - (U32)EC->pU8_BitStream - EC->uBase;
|
|
|
|
{
|
|
pBsInfoStream = (T_RTP_H261_BSINFO *)EC->pBsInfoStream;
|
|
|
|
if (uGOBN > 1) //avoid break between uMBA=0 and GOB header.
|
|
{
|
|
if (uNewBytes)
|
|
{
|
|
EC->uBase += uNewBytes;
|
|
pBsInfoStream->uBitOffset = uBitOffset + EC->uBase*8; //next bit
|
|
}
|
|
else
|
|
{
|
|
goto nobreak;
|
|
}
|
|
}
|
|
else
|
|
pBsInfoStream->uBitOffset = 0;
|
|
|
|
pBsInfoStream->uFlags = 0;
|
|
pBsInfoStream->u8MBA = 0;
|
|
pBsInfoStream->u8Quant = 0; // invalid Quant to signal packet starts a GOB
|
|
//pBsInfoStream->u8GOBN =(U8)uGOBN;
|
|
pBsInfoStream->u8GOBN = 0;
|
|
pBsInfoStream->i8HMV = 0;
|
|
pBsInfoStream->i8VMV = 0;
|
|
|
|
EC->uNumOfPackets++;
|
|
#ifndef RING0
|
|
#ifdef _DEBUG
|
|
{ char msg[120];
|
|
wsprintf(msg, "uFlag =%d,BitOffset=%d, MBA=%d, uQuant=%d,GOBN=%d,pBitStream=%lx,PacketSize= %d B",
|
|
pBsInfoStream->uFlags,
|
|
pBsInfoStream->uBitOffset,
|
|
pBsInfoStream->u8MBA,
|
|
pBsInfoStream->u8Quant,
|
|
pBsInfoStream->u8GOBN,
|
|
(U32)pBitStream,
|
|
uNewBytes);
|
|
DBOUT(msg);
|
|
}
|
|
#endif
|
|
#endif
|
|
EC->pBsInfoStream= (void *) ++pBsInfoStream; //create a new packet
|
|
|
|
}
|
|
nobreak:
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void H261RTP_TermBsInfoStream(T_H263EncoderCatalog * EC)
|
|
{
|
|
|
|
#ifndef RING0
|
|
#ifdef _DEBUG
|
|
DBOUT("BsInfoStream freed....");
|
|
#endif
|
|
#endif
|
|
|
|
if ( EC->hBsInfoStream)
|
|
{
|
|
GlobalUnlock(EC->hBsInfoStream);
|
|
GlobalFree(EC->hBsInfoStream);
|
|
}
|
|
EC->hBsInfoStream= NULL;
|
|
return;
|
|
}
|
|
|
|
#define DONTCARE 0
|
|
|
|
/*************************************************
|
|
* Return the maximum size of EBS (i.e. RTP part)
|
|
* including maximum of 3 bytes required for aligning
|
|
* start of EBS
|
|
************************************************/
|
|
U32 H261RTP_GetMaxBsInfoStreamSize(
|
|
T_H263EncoderCatalog * EC
|
|
)
|
|
{
|
|
return (3 + (EC->uNumOfPackets *sizeof(T_RTP_H261_BSINFO)) + sizeof(T_H26X_RTP_BSINFO_TRAILER));
|
|
}
|
|
|
|
|
|
U32 H261RTP_AttachBsInfoStream(
|
|
T_H263EncoderCatalog * EC,
|
|
U8 *lpOutput,
|
|
U32 uSize
|
|
)
|
|
{ U32 uIncreasedSize;
|
|
T_H26X_RTP_BSINFO_TRAILER BsInfoTrailer;
|
|
T_RTP_H261_BSINFO *pBsInfoStream ;
|
|
U8 * lpAligned;
|
|
//build bsinfo for the last packets
|
|
BsInfoTrailer.uVersion = H26X_RTP_PAYLOAD_VERSION;
|
|
BsInfoTrailer.uFlags = 0;
|
|
|
|
if (EC->PictureHeader.PicCodType == INTRAPIC)
|
|
BsInfoTrailer.uFlags |= RTP_H26X_INTRA_CODED;
|
|
|
|
|
|
BsInfoTrailer.uUniqueCode = H261_RTP_BS_START_CODE;
|
|
BsInfoTrailer.uCompressedSize = uSize;
|
|
BsInfoTrailer.uNumOfPackets = EC->uNumOfPackets;
|
|
BsInfoTrailer.u8Src = 0;
|
|
BsInfoTrailer.u8TR = EC->PictureHeader.TR;
|
|
BsInfoTrailer.u8TRB = DONTCARE;
|
|
BsInfoTrailer.u8DBQ = DONTCARE;
|
|
//update size feild for the last BsInfoTrailer
|
|
pBsInfoStream = (T_RTP_H261_BSINFO *)EC->pBsInfoStream;
|
|
|
|
uIncreasedSize = EC->uNumOfPackets *sizeof(T_RTP_H261_BSINFO);
|
|
lpAligned =(U8 *)( (U32)(lpOutput + uSize + 3 ) & 0xfffffffc);
|
|
memcpy( lpAligned,
|
|
EC->pBaseBsInfoStream,
|
|
uIncreasedSize);
|
|
memcpy(lpAligned + uIncreasedSize,
|
|
&BsInfoTrailer,
|
|
sizeof(T_H26X_RTP_BSINFO_TRAILER));
|
|
|
|
EC->pBsInfoStream = EC->pBaseBsInfoStream;
|
|
EC->uBase =0;
|
|
EC->uNumOfPackets=0;
|
|
|
|
uIncreasedSize += sizeof(T_H26X_RTP_BSINFO_TRAILER)+ (U32)(lpAligned- lpOutput-uSize);
|
|
|
|
return uIncreasedSize;
|
|
}
|
|
|
|
I32 H261RTP_RewindBsInfoStream(T_H263EncoderCatalog *EC, U32 uGOBN)
|
|
{
|
|
T_RTP_H261_BSINFO *pBsInfoStream;
|
|
|
|
pBsInfoStream = (T_RTP_H261_BSINFO *) EC->pBsInfoStream;
|
|
|
|
pBsInfoStream--;
|
|
|
|
while ( ! ((pBsInfoStream->u8GOBN == 0) &&
|
|
(pBsInfoStream->u8Quant == 0)
|
|
)
|
|
)
|
|
{
|
|
EC->uNumOfPackets--;
|
|
pBsInfoStream--;
|
|
}
|
|
|
|
EC->pBsInfoStream = (void *) ++pBsInfoStream;
|
|
return TRUE;
|
|
|
|
}
|