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