본 소스는http://iphome.hhi.de/suehring/tml/doc/lenc/html/rtp_8c-source.html 에서 발췌하였음을 밝힙니다.
rtp.c
Go to the documentation of this file.
0000100002/*!00003*****************************************************************************00004*00005* \file rtp.c00006*00007* \brief00008* Functions to handle RTP headers and packets per RFC1889 and RTP NAL spec00009* Functions support little endian systems only (Intel, not Motorola/Sparc)00010*00011* \date00012* 30 September 200100013*00014* \author00015* Stephan Wenger stewe@cs.tu-berlin.de00016*****************************************************************************/0001700018#include <stdlib.h>00019#include <assert.h>00020#include <memory.h>0002100022#include "global.h"0002300024#include "rtp.h"0002500026// A little trick to avoid those horrible #if TRACE all over the source code00027#if TRACE00028#define SYMTRACESTRING(s) strncpy(sym.tracestring,s,TRACESTRING_SIZE)00029#else00030#define SYMTRACESTRING(s) // to nothing00031#endif000320003300034intCurrentRTPTimestamp= 0;//! The RTP timestamp of the current packet,00035//! incremented with all P and I frames00036intCurrentRTPSequenceNumber= 0;//! The RTP sequence number of the current packet00037//! incremented by one for each sent packet0003800039FILE *f;00040/*!00041*****************************************************************************00042*00043* \brief00044* ComposeRTPpacket composes the complete RTP packet using the various00045* structure members of the RTPpacket_t structure00046*00047* \return00048* 0 in case of success00049* negative error code in case of failure00050*00051* \par Parameters00052* Caller is responsible to allocate enough memory for the generated packet00053* in parameter->packet. Typically a malloc of 12+paylen bytes is sufficient00054*00055* \par Side effects00056* none00057*00058* \note00059* Function contains assert() tests for debug purposes (consistency checks00060* for RTP header fields00061*00062* \date00063* 30 Spetember 200100064*00065* \author00066* Stephan Wenger stewe@cs.tu-berlin.de00067*****************************************************************************/000680006900070intComposeRTPPacket(RTPpacket_t*p)0007100072 {00073// Consistency checks through assert, only used for debug purposes00074 assert (p->v== 2);00075 assert (p->p== 0);00076 assert (p->x== 0);00077 assert (p->cc== 0);// mixer designers need to change this one00078 assert (p->m== 0 || p->m== 1);00079 assert (p->pt< 128);00080 assert (p->seq< 65536);00081 assert (p->payload!= NULL);00082 assert (p->paylen< 65536 - 40);// 2**16 -40 for IP/UDP/RTP header00083 assert (p->packet!= NULL);0008400085// Compose RTP header, little endian0008600087 p->packet[0] = ( (p->v)00088 | (p->p<< 2)00089 | (p->x<< 3)00090 | (p->cc<< 4) );00091 p->packet[1] = ( (p->m)00092 | (p->pt<< 1) );00093 p->packet[2] = p->seq& 0xff;00094 p->packet[3] = (p->seq>> 8) & 0xff;0009500096 memcpy (&p->packet[4], &p->timestamp, 4);// change to shifts for unified byte sex00097 memcpy (&p->packet[8], &p->ssrc, 4);// change to shifts for unified byte sex0009800099// Copy payload0010000101 memcpy (&p->packet[12], p->payload, p->paylen);00102 p->packlen= p->paylen+12;00103return0;00104 }00105001060010700108/*!00109*****************************************************************************00110*00111* \brief00112* WriteRTPPacket writes the supplied RTP packet to the output file00113*00114* \return00115* 0 in case of access00116* <0 in case of write failure (typically fatal)00117*00118* \param p00119* the RTP packet to be written (after ComposeRTPPacket() )00120* \param f00121* output file00122*00123* \date00124* October 23, 200100125*00126* \author00127* Stephan Wenger stewe@cs.tu-berlin.de00128*****************************************************************************/0012900130intWriteRTPPacket(RTPpacket_t*p, FILE *f)0013100132 {00133intintime = -1;0013400135 assert (f != NULL);00136 assert (p != NULL);001370013800139if(1 != fwrite (&p->packlen, 4, 1, f))00140return-1;00141if(1 != fwrite (&intime, 4, 1, f))00142return-1;00143if(1 != fwrite (p->packet, p->packlen, 1, f))00144return-1;00145return0;00146 }001470014800149001500015100152/*!00153*****************************************************************************00154*00155* \brief00156* int RTPWriteNALU write a NALU to the RTP file00157*00158* \return00159* Number of bytes written to output file00160*00161* \par Side effects00162* Packet written, RTPSequenceNumber and RTPTimestamp updated00163*00164* \date00165* December 13, 200200166*00167* \author00168* Stephan Wenger stewe@cs.tu-berlin.de00169*****************************************************************************/001700017100172intWriteRTPNALU(NALU_t*n)00173 {00174RTPpacket_t*p;0017500176 assert (f!= NULL);00177 assert (n != NULL);00178 assert (n->len< 65000);0017900180 n->buf[0] =00181 n->forbidden_bit<< 7 |00182 n->nal_reference_idc<< 5 |00183 n->nal_unit_type;0018400185// Set RTP structure elements and alloca() memory foor the buffers00186if((p = (RTPpacket_t*) malloc (sizeof(RTPpacket_t))) == NULL)00187no_mem_exit("RTPWriteNALU-1");00188if((p->packet= malloc (MAXRTPPACKETSIZE)) == NULL)00189no_mem_exit("RTPWriteNALU-2");00190if((p->payload= malloc (MAXRTPPACKETSIZE)) == NULL)00191no_mem_exit("RTPWriteNALU-3");0019200193 p->v=2;00194 p->p=0;00195 p->x=0;00196 p->cc=0;00197 p->m=(n->startcodeprefix_len==4)&1;// a long startcode of Annex B sets marker bit of RTP00198// Not exactly according to the RTP paylaod spec, but00199// good enough for now (hopefully).00200//! For error resilience work, we need the correct00201//! marker bit. Introduce a nalu->marker and set it in00202//! terminate_slice()?00203p->pt=H26LPAYLOADTYPE;00204 p->seq=CurrentRTPSequenceNumber++;00205 p->timestamp=CurrentRTPTimestamp;00206 p->ssrc=H26LSSRC;00207 p->paylen= n->len;00208 memcpy (p->payload, n->buf, n->len);00209002100021100212// Generate complete RTP packet00213if(ComposeRTPPacket(p) < 0)00214 {00215 printf ("Cannot compose RTP packet, exit\n");00216 exit (-1);00217 }00218if(WriteRTPPacket(p,f) < 0)00219 {00220 printf ("Cannot write %d bytes of RTP packet to outfile, exit\n", p->packlen);00221 exit (-1);00222 }00223 free (p->packet);00224 free (p->payload);00225 free (p);00226return(n->len* 8);00227 }002280022900230/*!00231********************************************************************************************00232* \brief00233* RTPUpdateTimestamp: patches the RTP timestamp depending on the TR00234*00235* \param00236* tr: TRof the following NALUs00237*00238* \return00239* none.00240*00241********************************************************************************************00242*/002430024400245voidRTPUpdateTimestamp(inttr)00246 {00247intdelta;00248staticintoldtr = -1;0024900250if(oldtr == -1)// First invocation00251 {00252CurrentRTPTimestamp= 0;//! This is a violation of the security req. of00253//! RTP (random timestamp), but easier to debug00254oldtr = 0;00255return;00256 }0025700258/*! The following code assumes a wrap around of TR at 256, and00259needs to be changed as soon as this is no more true.0026000261The support for B frames is a bit tricky, because it is not easy to distinguish00262between a natural wrap-around of the tr, and the intentional going back of the00263tr because of a B frame. It is solved here by a heuristic means: It is assumed that00264B frames are never "older" than 10 tr ticks. Everything higher than 10 is considered00265a wrap around.00266*/0026700268 delta = tr - oldtr;0026900270if(delta < -10)// wrap-around00271 delta+=256;0027200273CurrentRTPTimestamp+= delta *RTP_TR_TIMESTAMP_MULT;00274 oldtr = tr;00275 }002760027700278/*!00279********************************************************************************************00280* \brief00281* Opens the output file for the RTP packet stream00282*00283* \param Filename00284* The filename of the file to be opened00285*00286* \return00287* none. Function terminates the program in case of an error00288*00289********************************************************************************************00290*/0029100292voidOpenRTPFile(char*Filename)00293 {00294if((f= fopen (Filename,"wb")) == NULL)00295 {00296 printf ("Fatal: cannot open bitstream file '%s', exit (-1)\n", Filename);00297 exit (-1);00298 }00299 }003000030100302/*!00303********************************************************************************************00304* \brief00305* Closes the output file for the RTP packet stream00306*00307* \return00308* none. Function terminates the program in case of an error00309*00310********************************************************************************************00311*/0031200313voidCloseRTPFile()00314 {00315 fclose(f);00316 }003170031800319003200032100322003230032400325#if 000326/*!00327*****************************************************************************00328*00329* \brief00330* int aggregationRTPWriteBits (int marker) write the Slice header for the RTP NAL00331*00332* \return00333* Number of bytes written to output file00334*00335* \param marker00336* marker bit,00337*00338* \par Side effects00339* Packet written, RTPSequenceNumber and RTPTimestamp updated00340*00341* \date00342* September 10, 200200343*00344* \author00345* Dong Tian tian@cs.tut.fi00346*****************************************************************************/0034700348intaggregationRTPWriteBits (intMarker,intPacketType,intsubPacketType,void* bitstream,00349intBitStreamLenInByte, FILE *out)00350 {00351RTPpacket_t*p;00352intoffset;0035300354// printf( "writing aggregation packet...\n");00355 assert (out != NULL);00356 assert (BitStreamLenInByte < 65000);00357 assert (bitstream != NULL);00358 assert ((PacketType&0xf) == 4);0035900360// Set RTP structure elements and alloca() memory foor the buffers00361 p = (RTPpacket_t*) alloca (sizeof(RTPpacket_t));00362 p->packet=alloca (MAXRTPPACKETSIZE);00363 p->payload=alloca (MAXRTPPACKETSIZE);00364 p->v=2;00365 p->p=0;00366 p->x=0;00367 p->cc=0;00368 p->m=Marker&1;00369 p->pt=H26LPAYLOADTYPE;00370 p->seq=CurrentRTPSequenceNumber++;00371 p->timestamp=CurrentRTPTimestamp;00372 p->ssrc=H26LSSRC;0037300374 offset = 0;00375 p->payload[offset++] = PacketType;// This is the first byte of the compound packet0037600377// FIRST, write the sei message to aggregation packet, if it is available00378if(HaveAggregationSEI() )00379 {00380 p->payload[offset++] =sei_message[AGGREGATION_SEI].subPacketType;// this is the first byte of the first subpacket00381 *(short*)&(p->payload[offset]) =sei_message[AGGREGATION_SEI].payloadSize;00382 offset += 2;00383 memcpy (&p->payload[offset],sei_message[AGGREGATION_SEI].data,sei_message[AGGREGATION_SEI].payloadSize);00384 offset +=sei_message[AGGREGATION_SEI].payloadSize;0038500386clear_sei_message(AGGREGATION_SEI);00387 }0038800389// SECOND, write other payload to the aggregation packet00390// to do ...0039100392// LAST, write the slice data to the aggregation packet00393 p->payload[offset++] = subPacketType;// this is the first byte of the second subpacket00394 *(short*)&(p->payload[offset]) = BitStreamLenInByte;00395 offset += 2;00396 memcpy (&p->payload[offset], bitstream, BitStreamLenInByte);00397 offset += BitStreamLenInByte;0039800399 p->paylen= offset;// 1 +3 +seiPayload.payloadSize +3 +BitStreamLenInByte0040000401// Now the payload is ready, we can ...00402// Generate complete RTP packet00403if(ComposeRTPPacket(p) < 0)00404 {00405 printf ("Cannot compose RTP packet, exit\n");00406 exit (-1);00407 }00408if(WriteRTPPacket(p, out) < 0)00409 {00410 printf ("Cannot write %d bytes of RTP packet to outfile, exit\n", p->packlen);00411 exit (-1);00412 }00413return(p->packlen);0041400415 }004160041700418/*!00419*****************************************************************************00420* \isAggregationPacket00421* \brief00422* Determine if current packet is normal packet or compound packet (aggregation00423* packet)00424*00425* \return00426* return TRUE, if it is compound packet.00427* return FALSE, otherwise.00428*00429* \date00430* September 10, 200200431*00432* \author00433* Dong Tian tian@cs.tut.fi00434*****************************************************************************/00435BooleanisAggregationPacket()00436 {00437if(HaveAggregationSEI())00438 {00439returnTRUE;00440 }00441// Until Sept 2002, the JM will produce aggregation packet only for some SEI messages0044200443returnFALSE;00444 }0044500446/*!00447*****************************************************************************00448* \PrepareAggregationSEIMessage00449* \brief00450* Prepare the aggregation sei message.00451*00452* \date00453* September 10, 200200454*00455* \author00456* Dong Tian tian@cs.tut.fi00457*****************************************************************************/00458voidPrepareAggregationSEIMessage()00459 {00460Booleanhas_aggregation_sei_message = FALSE;00461// prepare the sei message here00462// write the spare picture sei payload to the aggregation sei message00463if(seiHasSparePicture&&img->type!= B_SLICE)00464 {00465FinalizeSpareMBMap();00466 assert(seiSparePicturePayload.data->byte_pos==seiSparePicturePayload.payloadSize);00467write_sei_message(AGGREGATION_SEI,seiSparePicturePayload.data->streamBuffer,seiSparePicturePayload.payloadSize, SEI_SPARE_PICTURE);00468 has_aggregation_sei_message = TRUE;00469 }00470// write the sub sequence information sei paylaod to the aggregation sei message00471if(seiHasSubseqInfo)00472 {00473FinalizeSubseqInfo(img->layer);00474write_sei_message(AGGREGATION_SEI,seiSubseqInfo[img->layer].data->streamBuffer,seiSubseqInfo[img->layer].payloadSize, SEI_SUBSEQ_INFORMATION);00475ClearSubseqInfoPayload(img->layer);00476 has_aggregation_sei_message = TRUE;00477 }00478// write the sub sequence layer information sei paylaod to the aggregation sei message00479if(seiHasSubseqLayerInfo&&img->number== 0)00480 {00481FinalizeSubseqLayerInfo();00482write_sei_message(AGGREGATION_SEI,seiSubseqLayerInfo.data,seiSubseqLayerInfo.payloadSize, SEI_SUBSEQ_LAYER_CHARACTERISTICS);00483seiHasSubseqLayerInfo= FALSE;00484 has_aggregation_sei_message = TRUE;00485 }00486// write the sub sequence characteristics payload to the aggregation sei message00487if(seiHasSubseqChar)00488 {00489FinalizeSubseqChar();00490write_sei_message(AGGREGATION_SEI,seiSubseqChar.data->streamBuffer,seiSubseqChar.payloadSize, SEI_SUBSEQ_CHARACTERISTICS);00491ClearSubseqCharPayload();00492 has_aggregation_sei_message = TRUE;00493 }00494// write the pan scan rectangle info sei playload to the aggregation sei message00495if(seiHasPanScanRectInfo)00496 {00497FinalizePanScanRectInfo();00498write_sei_message(AGGREGATION_SEI,seiPanScanRectInfo.data->streamBuffer,seiPanScanRectInfo.payloadSize, SEI_PANSCAN_RECT);00499ClearPanScanRectInfoPayload();00500 has_aggregation_sei_message = TRUE;00501 }00502// write the arbitrary (unregistered) info sei playload to the aggregation sei message00503if(seiHasUser_data_unregistered_info)00504 {00505FinalizeUser_data_unregistered();00506write_sei_message(AGGREGATION_SEI,seiUser_data_unregistered.data->streamBuffer,seiUser_data_unregistered.payloadSize, SEI_USER_DATA_UNREGISTERED);00507ClearUser_data_unregistered();00508 has_aggregation_sei_message = TRUE;00509 }00510// write the arbitrary (unregistered) info sei playload to the aggregation sei message00511if(seiHasUser_data_registered_itu_t_t35_info)00512 {00513FinalizeUser_data_registered_itu_t_t35();00514write_sei_message(AGGREGATION_SEI,seiUser_data_registered_itu_t_t35.data->streamBuffer,seiUser_data_registered_itu_t_t35.payloadSize, SEI_USER_DATA_REGISTERED_ITU_T_T35);00515ClearUser_data_registered_itu_t_t35();00516 has_aggregation_sei_message = TRUE;00517 }00518//write RandomAccess info sei payload to the aggregation sei message00519if(seiHasRandomAccess_info)00520 {00521FinalizeRandomAccess();00522write_sei_message(AGGREGATION_SEI, seiRandomAccess.data->streamBuffer, seiRandomAccess.payloadSize, SEI_RANDOM_ACCESS_POINT);00523ClearRandomAccess();00524 has_aggregation_sei_message = TRUE;00525 }00526// more aggregation sei payload is written here...0052700528// JVT-D099 write the scene information SEI payload00529if(seiHasSceneInformation)00530 {00531FinalizeSceneInformation();00532write_sei_message(AGGREGATION_SEI,seiSceneInformation.data->streamBuffer,seiSceneInformation.payloadSize, SEI_SCENE_INFORMATION);00533 has_aggregation_sei_message = TRUE;00534 }00535// End JVT-D0990053600537// after all the sei payload is written00538if(has_aggregation_sei_message)00539finalize_sei_message(AGGREGATION_SEI);00540 }0054100542/*!00543*****************************************************************************00544* \begin_sub_sequence_rtp00545* \brief00546* do some initialization for sub-sequence under rtp00547*00548* \date00549* September 10, 200200550*00551* \author00552* Dong Tian tian@cs.tut.fi00553*****************************************************************************/0055400555voidbegin_sub_sequence_rtp()00556 {00557if(input->of_mode!=PAR_OF_RTP||input->NumFramesInELSubSeq== 0 )00558return;0055900560// begin to encode the base layer subseq00561if(IMG_NUMBER== 0 )00562 {00563// printf("begin to encode the base layer subseq\n");00564InitSubseqInfo(0);00565if(1)00566UpdateSubseqChar();00567 }00568// begin to encode the enhanced layer subseq00569if(IMG_NUMBER% (input->NumFramesInELSubSeq+1) == 1 )00570 {00571// printf("begin to encode the enhanced layer subseq\n");00572InitSubseqInfo(1);// init the sub-sequence in the enhanced layer00573// add_dependent_subseq(1);00574if(1)00575UpdateSubseqChar();00576 }00577 }0057800579/*!00580*****************************************************************************00581* \end_sub_sequence_rtp00582* \brief00583* do nothing00584*00585* \date00586* September 10, 200200587*00588* \author00589* Dong Tian tian@cs.tut.fi00590*****************************************************************************/00591voidend_sub_sequence_rtp()00592 {00593// end of the base layer:00594if(img->number==input->no_frames-1 )00595 {00596// printf("end of encoding the base layer subseq\n");00597CloseSubseqInfo(0);00598// updateSubSequenceBox(0);00599 }00600// end of the enhanced layer:00601if( ((IMG_NUMBER%(input->NumFramesInELSubSeq+1)==0) && (input->successive_Bframe!= 0) && (IMG_NUMBER>0)) ||// there are B frames00602 ((IMG_NUMBER%(input->NumFramesInELSubSeq+1)==input->NumFramesInELSubSeq) && (input->successive_Bframe==0))// there are no B frames00603 )00604 {00605// printf("end of encoding the enhanced layer subseq\n");00606CloseSubseqInfo(1);00607// add_dependent_subseq(1);00608// updateSubSequenceBox(1);00609 }00610 }0061100612#endif00613
Documentation generated withDoxyGen
rtp.c File Reference
Functions to handle RTP headers and packets per RFC1889 and RTP NAL spec Functions support little endian systems only (Intel, not Motorola/Sparc).More...
#include <stdlib.h>
#include <assert.h>
#include <memory.h>
#include "global.h"
#include "rtp.h"
Include dependency graph for rtp.c:
Go to the source code of this file.
Defines | |
#define | SYMTRACESTRING(s) |
Functions | |
int | ComposeRTPPacket(RTPpacket_t*p) |
int | WriteRTPPacket(RTPpacket_t*p, FILE *f) |
int | WriteRTPNALU(NALU_t*n) |
void | RTPUpdateTimestamp(int tr) |
void | OpenRTPFile(char *Filename) |
void | CloseRTPFile() |
Variables | |
int | CurrentRTPTimestamp= 0 |
int | CurrentRTPSequenceNumber= 0 |
FILE * | f |
Detailed Description
Functions to handle RTP headers and packets per RFC1889 and RTP NAL spec Functions support little endian systems only (Intel, not Motorola/Sparc).
- Date:
- 30 September 2001
- Author:
- Stephan Wengerstewe@cs.tu-berlin.de
Definition in filertp.c.
Function Documentation
|
Closes the output file for the RTP packet stream.
Definition at line313of filertp.c. Referencesf. Referenced byterminate_sequence(). |
|
ComposeRTPpacket composes the complete RTP packet using the various structure members of theRTPpacket_tstructure.
Definition at line70of filertp.c. ReferencesRTPpacket_t::cc,RTPpacket_t::m,RTPpacket_t::p,RTPpacket_t::packet,RTPpacket_t::packlen,RTPpacket_t::paylen,RTPpacket_t::payload,RTPpacket_t::pt,RTPpacket_t::seq,RTPpacket_t::ssrc,RTPpacket_t::timestamp,RTPpacket_t::v, andRTPpacket_t::x. Referenced byWriteRTPNALU(). |
|
Opens the output file for the RTP packet stream.
Definition at line292of filertp.c. Referencesf. Referenced bystart_sequence(). |
|
RTPUpdateTimestamp: patches the RTP timestamp depending on the TR.
The following code assumes a wrap around of TR at 256, and needs to be changed as soon as this is no more true. The support for B frames is a bit tricky, because it is not easy to distinguish between a natural wrap-around of the tr, and the intentional going back of the tr because of a B frame. It is solved here by a heuristic means: It is assumed that B frames are never "older" than 10 tr ticks. Everything higher than 10 is considered a wrap around. Definition at line245of filertp.c. ReferencesCurrentRTPTimestamp, andRTP_TR_TIMESTAMP_MULT. Referenced bystart_slice(). |
|
int RTPWriteNALU write a NALU to the RTP file
Definition at line172of filertp.c. ReferencesNALU_t::buf,RTPpacket_t::cc,ComposeRTPPacket(),CurrentRTPSequenceNumber,CurrentRTPTimestamp,f,NALU_t::forbidden_bit,H26LPAYLOADTYPE,H26LSSRC,NALU_t::len,RTPpacket_t::m,MAXRTPPACKETSIZE,NALU_t::nal_reference_idc,NALU_t::nal_unit_type,no_mem_exit(),RTPpacket_t::p,RTPpacket_t::packet,RTPpacket_t::paylen,RTPpacket_t::payload,RTPpacket_t::pt,RTPpacket_t::seq,RTPpacket_t::ssrc,NALU_t::startcodeprefix_len,RTPpacket_t::timestamp,RTPpacket_t::v,WriteRTPPacket(), andRTPpacket_t::x. Referenced bystart_sequence(). Here is the call graph for this function: |
|
WriteRTPPacket writes the supplied RTP packet to the output file.
Definition at line130of filertp.c. ReferencesRTPpacket_t::packet, andRTPpacket_t::packlen. Referenced byWriteRTPNALU(). |
Variable Documentation
|
The RTP timestamp of the current packet, incremented with all P and I frames Definition at line36of filertp.c. Referenced byWriteRTPNALU(). |
|
The RTP sequence number of the current packet incremented by one for each sent packet |
Documentation generated withDoxyGen
댓글