?? rtp.c
字號:
* \date * October 24, 2001 * * \author * Stephan Wenger stewe@cs.tu-berlin.de *****************************************************************************/int RTPSequenceHeader (FILE *out){ RTPpacket_t *p; assert (out != NULL); // Set RTP structure elements and alloca() memory foor the buffers p = (RTPpacket_t *) alloca (sizeof (RTPpacket_t)); p->packet=alloca (MAXRTPPACKETSIZE); p->payload=alloca (MAXRTPPACKETSIZE); p->v=2; p->p=0; p->x=0; p->cc=0; p->m=1; p->pt=H26LPAYLOADTYPE; p->seq=CurrentRTPSequenceNumber++; p->timestamp=CurrentRTPTimestamp; p->ssrc=H26LSSRC; // Set First Byte of RTP payload, see VCEG-N72r1 p->payload[0] = 6 | // Parameter Update Packet 0 | // no know error 0; // reserved // Generate the Parameter update SDP syntax, donm't overwrite First Byte p->paylen = 1 + ComposeHeaderPacketPayload (&p->payload[1]); // Generate complete RTP packet if (ComposeRTPPacket (p) < 0) { printf ("Cannot compose RTP packet, exit\n"); exit (-1); } if (WriteRTPPacket (p, out) < 0) { printf ("Cannot write %d bytes of RTP packet to outfile, exit\n", p->packlen); exit (-1); } return (p->packlen);}/*! ***************************************************************************** * * \brief * int RTPSliceHeader () write the Slice header for the RTP NAL * * \return * Number of bits used by the slice header * * \para Parameters * none * * \para Side effects * Slice header as per VCEG-N72r2 is written into the appropriate partition * bit buffer * * \para Limitations/Shortcomings/Tweaks * The current code does not support the change of picture parameters within * one coded sequence, hence there is only one parameter set necessary. This * is hard coded to zero. * As per Email deiscussions on 10/24/01 we decided to include the SliceID * into both the Full Slice pakcet and Partition A packet * * \date * October 24, 2001 * * \author * Stephan Wenger stewe@cs.tu-berlin.de *****************************************************************************/int RTPSliceHeader(){ int dP_nr = assignSE2partition[input->partition_mode][SE_HEADER]; Bitstream *currStream = ((img->currentSlice)->partArr[dP_nr]).bitstream; DataPartition *partition = &((img->currentSlice)->partArr[dP_nr]); SyntaxElement sym; int len = 0; int RTPSliceType; assert (input->of_mode == PAR_OF_RTP); sym.type = SE_HEADER; // This will be true for all symbols generated here sym.mapping = n_linfo2; // Mapping rule: Simple code number to len/info SYMTRACESTRING("RTP-SH: Parameter Set"); sym.value1 = 0; len += writeSyntaxElement_UVLC (&sym, partition); SYMTRACESTRING("RTP-SH: Picture ID"); sym.value1 = img->currentSlice->picture_id;// printf ("Put PictureId %d\n", img->currentSlice->picture_id); len += writeSyntaxElement_UVLC (&sym, partition); /*! StW: // Note: we currently do not support mixed slice types in the encoder, hence // we use the picture type here (although there is no such thing as a picture // type any more) // // This needs to be double checked against the document. Email inquiery on // 10/24 evening: is there a need for distinguishing the multpred P from regular // P? if so, this has to be revisited! // // StW bug fix: write Slice type according to document */ switch (img->type) { case INTER_IMG: if (img->types==SP_IMG) RTPSliceType = 2; else RTPSliceType = 0; break; case INTRA_IMG: RTPSliceType = 3; break; case B_IMG: RTPSliceType = 1; break; case SP_IMG: // That's what I would expect to be the case. But img->type contains INTER_IMG // here (see handling above) //! \todo make one variable from img->type and img->types RTPSliceType = 2; break; default: printf ("Panic: unknown picture type %d, exit\n", img->type); exit (-1); } SYMTRACESTRING("RTP-SH: Slice Type"); sym.value1 = RTPSliceType; len += writeSyntaxElement_UVLC (&sym, partition); SYMTRACESTRING("RTP-SH: FirstMBInSliceX"); sym.value1 = img->mb_x; len += writeSyntaxElement_UVLC (&sym, partition); SYMTRACESTRING("RTP-SH: FirstMBinSlinceY"); sym.value1 = img->mb_y; len += writeSyntaxElement_UVLC (&sym, partition); SYMTRACESTRING("RTP-SH: InitialQP"); sym.value1 = 31-img->qp; len += writeSyntaxElement_UVLC (&sym, partition); if (img->types==SP_IMG) { SYMTRACESTRING("RTP-SH: SP InitialQP"); sym.value1 = 31-img->qpsp; len += writeSyntaxElement_UVLC (&sym, partition); } /*! StW: // Note: VCEG-N72 says that the slice type UVLC is not present in single // slice packets. Generally, the NAL allows to mix Single Slice and Partitioning, // however, the software does not. Hence it is sufficient here to express // the dependency by checkling the input parameter */ if (input->partition_mode == PAR_DP_3) { SYMTRACESTRING("RTP-SH: Slice ID"); sym.value1 = img->current_slice_nr; len += writeSyntaxElement_UVLC (&sym, partition); } // After this, and when in CABAC mode, terminateSlice() may insert one more // UVLC codeword for the number of coded MBs return len;}/*! ***************************************************************************** * * \brief * int RTPWriteBits (int marker) write the Slice header for the RTP NAL * * \return * Number of bytes written to output file * * \para Parameters * marker: markber bit, * * \para Side effects * Packet written, RTPSequenceNumber and RTPTimestamp updated * * \date * October 24, 2001 * * \author * Stephan Wenger stewe@cs.tu-berlin.de *****************************************************************************/int RTPWriteBits (int Marker, int PacketType, void * bitstream, int BitStreamLenInByte, FILE *out){ RTPpacket_t *p; assert (out != NULL); assert (BitStreamLenInByte < 65000); assert (bitstream != NULL); assert (PacketType < 4); // Set RTP structure elements and alloca() memory foor the buffers p = (RTPpacket_t *) alloca (sizeof (RTPpacket_t)); p->packet=alloca (MAXRTPPACKETSIZE); p->payload=alloca (MAXRTPPACKETSIZE); p->v=2; p->p=0; p->x=0; p->cc=0; p->m=Marker&1; p->pt=H26LPAYLOADTYPE; p->seq=CurrentRTPSequenceNumber++; p->timestamp=CurrentRTPTimestamp; p->ssrc=H26LSSRC; p->payload[0] = PacketType; p->paylen = 1 + BitStreamLenInByte; memcpy (&p->payload[1], bitstream, BitStreamLenInByte); // Generate complete RTP packet if (ComposeRTPPacket (p) < 0) { printf ("Cannot compose RTP packet, exit\n"); exit (-1); } if (WriteRTPPacket (p, out) < 0) { printf ("Cannot write %d bytes of RTP packet to outfile, exit\n", p->packlen); exit (-1); } return (p->packlen);}static int oldtr = -1;void RTPUpdateTimestamp (int tr){ int delta; if (oldtr == -1) // First invocation { CurrentRTPTimestamp = 0; //! This is a violation of the security req. of //! RTP (random timestamp), but easier to debug oldtr = 0; return; } /*! 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. I'm a bit at loss whether this is a fundamental problem of B frames. Does a decoder have to change its TR interpretation depenent on the picture type? Horrible -- we would have a fundamental problem when mixing slices. This needs careful review. */ delta = tr - oldtr; if (delta < -10) // wrap-around delta+=256; CurrentRTPTimestamp += delta * RTP_TR_TIMESTAMP_MULT; oldtr = tr;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -