📄 rtp.c
字号:
/* Reference Picture Selection Flags */
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &temp, &dummy);
bitptr+=len;
/* Picture Number */
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &sh->PictureNum, &dummy);
bitptr+=len;
/* Reference picture selection layer */
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &temp, &dummy);
bitptr+=len;
if (temp)
{
/* read Reference Picture Selection Layer */
// free old buffer content
while (sh->RMPNIbuffer)
{
tmp_rmpni=sh->RMPNIbuffer;
sh->RMPNIbuffer=tmp_rmpni->Next;
free (tmp_rmpni);
}
done=0;
/* if P or B frame RMPNI */
if ((sh->SliceType>=0)&&(sh->SliceType<=2))
{
do
{
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &tmp1, &dummy);
bitptr+=len;
// check for illegal values
if ((tmp1<0)||(tmp1>3))
error ("Invalid RMPNI operation specified",400);
if (tmp1!=3)
{
printf ("got RMPNI = %d\n",tmp1);
tmp_rmpni=(RMPNIbuffer_t*)calloc (1,sizeof (RMPNIbuffer_t));
tmp_rmpni->Next=NULL;
tmp_rmpni->RMPNI=tmp1;
// get the additional parameter
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &tmp_rmpni->Data, &dummy);
bitptr+=len;
// add RMPNI to list
if (sh->RMPNIbuffer==NULL)
{
sh->RMPNIbuffer=tmp_rmpni;
}
else
{
tmp_rmpni2=sh->RMPNIbuffer;
while (tmp_rmpni2->Next!=NULL)
tmp_rmpni2=tmp_rmpni2->Next;
tmp_rmpni2->Next=tmp_rmpni;
}
} else
{
// free temporary memory (no need to save end loop operation)
done=1;
}
} while (!done);
}
}
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &sh->RPBT, &dummy);
bitptr+=len;
// free old buffer content
while (sh->MMCObuffer)
{
tmp_mmco=sh->MMCObuffer;
sh->MMCObuffer=tmp_mmco->Next;
free (tmp_mmco);
}
/* read Memory Management Control Operation */
if (sh->RPBT)
{
do
{
tmp_mmco=(MMCObuffer_t*)calloc (1,sizeof (MMCObuffer_t));
tmp_mmco->Next=NULL;
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &tmp_mmco->MMCO, &dummy);
bitptr+=len;
switch (tmp_mmco->MMCO)
{
case 0:
case 5:
break;
case 1:
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &tmp_mmco->DPN, &dummy);
bitptr+=len;
break;
case 2:
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &tmp_mmco->LPIN, &dummy);
bitptr+=len;
break;
case 3:
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &tmp_mmco->DPN, &dummy);
bitptr+=len;
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &tmp_mmco->LPIN, &dummy);
bitptr+=len;
break;
case 4:
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &tmp_mmco->MLIP1, &dummy);
bitptr+=len;
break;
default:
error ("Invalid MMCO operation specified",400);
break;
}
// add MMCO to list
if (sh->MMCObuffer==NULL)
{
sh->MMCObuffer=tmp_mmco;
}
else
{
tmp_mmco2=sh->MMCObuffer;
while (tmp_mmco2->Next!=NULL) tmp_mmco2=tmp_mmco2->Next;
tmp_mmco2->Next=tmp_mmco;
}
}while (tmp_mmco->MMCO!=0);
}
/* end KS */
if (ParSet[sh->ParameterSet].EntropyCoding == 1) // CABAC in use, need to get LastMB
{
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &sh->CABAC_LastMB, &dummy);
bitptr+=len;
}
bytes = bitptr/8;
if (bitptr%8)
bytes++;
return bytes;
}
/*!
*****************************************************************************
*
* \brief
* Parses and interprets the UVLC-coded partition header (Type B and C packets only)
*
* \return
* negative in case of errors, the byte-index where the UVLC/CABAC MB data
* starts otherwise
* Side effects:
* sh->PictureID und sh->SliceID set, all other values unchanged
*
* \date
* 27 October, 2001
*
* \author
* Stephan Wenger stewe@cs.tu-berlin.de
*****************************************************************************/
int RTPInterpretPartitionHeader (byte *buf, int bufsize, RTPSliceHeader_t *sh)
{
int len, info, bytes, dummy, bitptr=0;
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &sh->PictureID, &dummy);
bitptr+=len;
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &sh->SliceID, &dummy);
bitptr+=len;
bytes = bitptr/8;
if (bitptr%8)
bytes++;
return bytes;
}
/*!
*****************************************************************************
*
* \brief
* Reads and interprets the RTP sequence header, expects a type 6 packet
*
* \return
*
* Side effects:
* sets several fields in the img-> and inp-> structure, see RTPUseParameterSet
*
* \date
* 27 October, 2001
*
* \author
* Stephan Wenger stewe@cs.tu-berlin.de
*****************************************************************************/
// Each RTP File is supposed to start with a type 6 (Header) packet. It is necessary
// to read this early on in order to allocate the memory for the decoder. This should
// be fixed some day in such a way that the decoder allocates memory as needed, and
// not statically at the first frame.
int RTPSequenceHeader (struct img_par *img, struct inp_par *inp, FILE *bits)
{
int TotalPackLen;
RTPpacket_t *p;
RTPSliceHeader_t *sh;
int err;
int intime=0;
assert (bits != NULL);
p=alloca (sizeof (RTPpacket_t));
sh=alloca(sizeof (RTPSliceHeader_t));
if (4 != fread (&TotalPackLen,1, 4, bits))
return -4711; // EOF inidication
if (4 != fread (&intime, 1, 4, bits))
return -4712;
p->packlen = TotalPackLen;
p->packet = alloca (p->packlen);
if (p->packlen != fread (p->packet, 1, p->packlen, bits))
{
// The corruption of a packet file is not a case we should handle.
// In a real-world system, RTP packets may get lost, but they will
// never get shortened. Hence, the error checked here cannot occur.
printf ("RTP File corruption, unexpected end of file, tried to read %d bytes\n", p->packlen);
return -4713; // EOF
}
p->paylen = p->packlen - 12; // 12 bytes RTP header
p->payload = alloca (p->paylen);
if (DecomposeRTPpacket (p) < 0)
{
// this should never happen, hence exit() is ok. We probably do not want to attempt
// to decode a packet that obviously wasn't generated by RTP
printf ("Errors reported by DecomposePacket(), exit\n");
exit (-700);
}
// Here the packet is ready for interpretation
assert (p->pt == H26LPAYLOADTYPE);
assert (p->ssrc == 0x12345678);
if (p->payload[0] != 6)
{
printf ("RTPSequenceHeader: Expect Header Packet (FirstByet = 6), found packet type %d\n", p->payload[0]);
exit (-1);
}
if ((err = RTPInterpretParameterSetPacket (&p->payload[1], p->paylen-1)) < 0)
{
printf ("RTPInterpretParameterSetPacket returns error %d\n", err);
}
RTPUseParameterSet (0, img, inp);
img->number = 0;
return 0;
}
/*!
*****************************************************************************
*
* \brief
* Sets various img->, inp-> and currSlice->struct members according to
* the contents of the sh-> slice header structure
*
* \return
*
* Side effects:
* Set img-> qp, current_slice_nr, type, tr
* Set inp->
* Set currSlice-> qp, start_mb_nr, slice_nr, picture_type, picture_id (CABAC only: last_mb_nr)
*
* \date
* 27 October, 2001
*
* \author
* Stephan Wenger stewe@cs.tu-berlin.de
*****************************************************************************/
void RTPSetImgInp (struct img_par *img, struct inp_par *inp, RTPSliceHeader_t *sh)
{
static int ActualPictureType;
Slice *currSlice = img->currentSlice;
RMPNIbuffer_t *tmp_rmpni;
MMCObuffer_t *tmp_mmco;
img->qp = currSlice->qp = sh->InitialQP;
if (sh->SliceType==2)
img->qpsp = sh->InitialSPQP;
currSlice->start_mb_nr = (img->width/16)*sh->FirstMBInSliceY+sh->FirstMBInSliceX;
switch (sh->SliceType)
{
//! Potential BUG: do we need to distinguish between INTER_IMG_MULT and INTER_IMG?
//! similar with B_IMG_! and B_IMG_MULT
//! also: need to define Slice types for SP images
//! see VCEG-N72r1 for the Slice types, which are mapped here to img->type
case 0:
img->type = currSlice->picture_type = ParSet[CurrentParameterSet].UseMultpred?INTER_IMG_MULT:INTER_IMG_1;
break;
case 1:
img->type = currSlice->picture_type = ParSet[CurrentParameterSet].UseMultpred?B_IMG_MULT:B_IMG_1;
break;
case 2:
img->type = currSlice->picture_type = ParSet[CurrentParameterSet].UseMultpred?SP_IMG_MULT:SP_IMG_1;
break;
case 3:
img->type = currSlice->picture_type = INTRA_IMG;
break;
default:
printf ("Panic: unknown Slice type %d, conceal by loosing slice\n", sh->SliceType);
currSlice->ei_flag = 1;
}
//! The purpose of the following is to check for mixed Slices in one picture.
//! According to VCEG-N72r1 and common sense this is allowed. However, the
//! current software seems to have a problem of some kind, to be checked. Hence,
//! printf a warning
if (currSlice->start_mb_nr == 0)
ActualPictureType = img->type;
else
if (ActualPictureType != img->type)
{
printf ("WARNING: mixed Slice types in a single picture -- interesting things may happen :-(\n");
}
img->tr = currSlice->picture_id = sh->PictureID;
currSlice->last_mb_nr = currSlice->start_mb_nr + sh->CABAC_LastMB;
if (currSlice->last_mb_nr == currSlice->start_mb_nr)
currSlice->last_mb_nr = img->max_mb_nr;
/* KS: Multi Frame Buffering Syntax */
img->pn=sh->PictureNum;
// clear old slice RMPNI command buffer
while (img->currentSlice->rmpni_buffer)
{
tmp_rmpni = img->currentSlice->rmpni_buffer;
img->currentSlice->rmpni_buffer=tmp_rmpni->Next;
free (tmp_rmpni);
}
img->currentSlice->rmpni_buffer=sh->RMPNIbuffer;
sh->RMPNIbuffer=NULL;
// free image MMCO buffer
while (img->mmco_buffer)
{
tmp_mmco=img->mmco_buffer;
img->mmco_buffer=tmp_mmco->Next;
free (tmp_mmco);
}
// set image mmco bufer to actual MMCO buffer
img->mmco_buffer=sh->MMCObuffer;
sh->MMCObuffer=NULL;
}
/*!
*****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -