📄 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 + -