📄 rtp.c
字号:
//! The following two variables are used to calculate the size of a lost slice.
//! The NAL conveyes this "lost" slice to the VCL with the ei_flag set in order
//! to trigger concealment
static int LastPicID; //! PicID of the last packet (current state of the decoder
//! before reading the next packet
static int ExpectedMBNr; //! MB Nr of the last decoded MB
/*!
************************************************************************
* \brief
* read all Partitions of one Slice from RTP packets
* \return
* SOS if this is not a new frame \n
* SOP if this is a new frame \n
* EOS if end of sequence reached
************************************************************************
*/
int readSliceRTP (struct img_par *img, struct inp_par *inp)
{
Slice *currSlice = img->currentSlice;
int PartitionMask;
static int CurrentPictureId = -1;
assert (currSlice != NULL);
PartitionMask = ReadRTPPacket (img, inp, bits);
/*
{
int i;
for (i=0; i<25; i++)
printf ("%02x ", currSlice->partArr[0].bitstream->streamBuffer[i]);
printf ("\n");
for (i=0; i<25; i++)
printf ("%02x ", currSlice->partArr[1].bitstream->streamBuffer[i]);
printf ("\n");
for (i=0; i<25; i++)
printf ("%02x ", currSlice->partArr[2].bitstream->streamBuffer[i]);
printf ("\n");
}
*/
if(PartitionMask == -4711)
return EOS;
if(CurrentPictureId == currSlice->picture_id)
return SOS;
else
{
CurrentPictureId = currSlice->picture_id;
return SOP;
}
}
/*!
************************************************************************
* \brief
* read all partitions of one slice from RTP packet stream, also handle
* any Parameter Update packets and SuUPP-Packets
* \return
* -1 for EOF \n
* Partition-Bitmask otherwise:
* Partition Bitmask: 0x1: Full Slice, 0x2: type A, 0x4: Type B
* 0x8: Type C
************************************************************************
*/
// Note: this is the unchanged code from the FMO implementation in C092.
// Needs serious testing w/DP and stuff.
int ReadRTPPacket (struct img_par *img, struct inp_par *inp, FILE *bits)
{
Slice *currSlice = img->currentSlice;
DecodingEnvironmentPtr dep;
byte *buf;
RTPpacket_t *p, *nextp;
RTPSliceHeader_t *sh, *nextsh;
int MBDataIndex;
int done = 0;
int err;//, back=0; // avoid warnings. mwi
int FirstMacroblockInSlice;
static int b_frame = FALSE;
// JVT-D101
int done0 = 0;
static int first = 1;
// End JVT-D101
assert (currSlice != NULL);
assert (bits != 0);
// Temporal storage for this function only
p=alloca (sizeof (RTPpacket_t)); // the RTP packet
p->packet=alloca (MAXRTPPACKETSIZE);
p->payload=alloca (MAXRTPPAYLOADLEN);
nextp=alloca (sizeof (RTPpacket_t));
sh=alloca(sizeof (RTPSliceHeader_t));
sh->RMPNIbuffer=NULL;
sh->MMCObuffer=NULL;
nextsh=alloca(sizeof (RTPSliceHeader_t));
nextsh->RMPNIbuffer=NULL;
nextsh->MMCObuffer=NULL;
ExpectedMBNr = img->current_mb_nr;
LastPicID = img->tr;
// JVT-D101
done0 = 0;
do
{
// End JVT-D101
done = 0;
do
{
if (RTPReadPacket (p, bits) < 0) // Read and decompose
return -4711;
if (p->payload[0] == (PAYLOAD_TYPE_IDERP<<4) && fb != NULL && frm != NULL ) // Tian Dong: IDERP, JVT-C083
{
reset_buffers();
frm->picbuf_short[0]->used=0;
frm->picbuf_short[0]->picID=-1;
frm->picbuf_short[0]->lt_picID=-1;
frm->short_used=0;
}
switch (p->payload[0] & 0xf)
{
case 0: // Full Slice packet
case 1: // Partition type A packet
done = 1;
break;
case 2: // Partition B
case 3: // Partition C
// Do nothing. this results in discarding the unexpected Partition B, C
// packet, which will later be concealed "automatically", because when
// interpreting the next Partition A or full slice packet a range of
// lost blocks is found which will be concealed in the usual manner.
//
// If anyonme comes up with an idea how to use coefficients without the
// header information then this code has to be changed
printf ("found unexpected Partition %c packet, skipping\n", (p->payload[0]&0xf)==2?'B':'C'); // avoid warnings. mwi
break;
case 4:
// Tian Dong (Sept 2002)
// The spare picture SEI messages are packetized in compound packet (known as aggregation packet now),
// I will only deal with the compound packet composed by sei message and slice data.
ProcessAggregationPacket(p, img);
done = 1;
break;
case 5:
//! Add implementation of SUPP packets here
printf ("SUPP packets not yet implemented, skipped\n");
break;
case 6:
printf ("Found header packet\n");
if ((err = RTPInterpretParameterSetPacket (&p->payload[1], p->paylen-1)) < 0)
{
printf ("RTPInterpretParameterSetPacket returns error %d\n", err);
}
break;
default:
printf ("Undefined packet type %d found, skipped\n", p->payload[0] & 0xf);
assert (0==1);
break;
}
} while (!done);
// Here, all the non-video data packets and lonely type B, C partitions
// are handled. Now work on the expected type A and full slice packets
assert ((p->payload[0] & 0xf) < 2);
if ((p->payload[0] & 0xf) == 0) // Full Slice packet
{
currSlice->ei_flag = 0;
MBDataIndex = 1; // Skip First Byte
MBDataIndex += RTPInterpretSliceHeader (&p->payload[1], p->paylen-1, 0, sh, img);
}
else // Partition A packet
{
currSlice->ei_flag = 0;
MBDataIndex = 1; // Skip First Byte
MBDataIndex += RTPInterpretSliceHeader (&p->payload[1], p->paylen-1, 1, sh, img);
}
FirstMacroblockInSlice = sh->FirstMBInSliceY * (img->width/16) +
sh->FirstMBInSliceX; //! assumes picture sizes divisble by 16
//JVT-D101
if(first) // just to let the decoding of the first slice in the session
{
done0 = 1;
first = 0;
}
else
{
if(sh->PictureID == currSlice->picture_id) // in same picture currSlice->picture_id
{
if(sh->PictureID == img->last_decoded_pic_id) // a redundant slice/picture
;
else if(FirstMacroblockInSlice >= img->current_mb_nr) // note here img->current_mb_nr = -4711 if the first slice of picture comes
done0 = 1; // if FirstMacroblockInSlice < img->current_mb_nr, the slice just read is a redundant slice
}
else
done0 = 1;
}
// End JVT-D101
} while (!done0); // JVT-D101
// Here used to be the if() cascade. It is deleted for two reasons: First,
// error concealment for non data-partitioned slices (Nokia concealment) is
// now triggered after decoding based on the map of decoded macroblocks, see
// file image.c. The DP errror concealment (Teles concealment) is triggered
// in ProcessDataPartitionedSlice(). Second, the old code made assumptions
// such as in-order slices and non-FMO macroblock ordering which are no more
// appropriate.
//! I believe I have included all relevant code regarding the IDERP handling
//! and the emu-prevention code. However, this would be the first place to
//! look if any of the two are broken (in the RTP file format only). StW, 06.07.02
// printf ("ReadRTPPacket: FirstMacroblockInSlice = %d\n", FirstMacroblockInSlice);
// Here, all concealment is done and we have either a type A partition
// packet or a full slice packet, which need to be worked on
RTPUseParameterSet (sh->ParameterSet, img, inp);
RTPSetImgInp(img, inp, sh);
free_Partition (currSlice->partArr[0].bitstream);
assert (p->paylen-MBDataIndex > 0);
currSlice->partArr[0].bitstream->read_len = 0;
currSlice->partArr[0].bitstream->code_len = p->paylen-MBDataIndex; // neu
currSlice->partArr[0].bitstream->bitstream_length = p->paylen-MBDataIndex;
memcpy (currSlice->partArr[0].bitstream->streamBuffer, &p->payload[MBDataIndex],p->paylen-MBDataIndex);
p->paylen = MBDataIndex + EBSPtoRBSP(currSlice->partArr[0].bitstream->streamBuffer, p->paylen - MBDataIndex, 0);
p->paylen = MBDataIndex + RBSPtoSODB(currSlice->partArr[0].bitstream->streamBuffer, p->paylen - MBDataIndex);
currSlice->partArr[0].bitstream->bitstream_length = p->paylen-MBDataIndex;
buf = currSlice->partArr[0].bitstream->streamBuffer;
if(active_pps->entropy_coding_mode == CABAC)
{
dep = &((currSlice->partArr[0]).de_cabac);
arideco_start_decoding(dep, buf, 0, &currSlice->partArr[0].bitstream->read_len, img->type);
}
currSlice->next_header = RTPGetFollowingSliceHeader (img, nextp, nextsh); // no use for the info in nextp, nextsh yet.
// printf ("ReadRTPPacket: currSlice->next_header %d RTPSequence %d\n", currSlice->next_header, p->seq);
assert (b_frame == 0);
if ((p->payload[0]&0xf) == 0 || b_frame) // Full Slice Packet or B-Frame
{
currSlice->dp_mode = PAR_DP_1;
currSlice->max_part_nr=1;
return 1;
}
else
{
currSlice->dp_mode = PAR_DP_3;
currSlice->max_part_nr = 3;
RTPProcessDataPartitionedSlice (img, inp, bits, p, sh->SliceID);
return 3;
}
return FALSE;
}
/*!
*****************************************************************************
*
* \brief
* Parses and interprets the UVLC-coded slice header
*
* \return
* negative in case of errors, the byte-index where the UVLC/CABAC MB data
* starts otherwise
*
* \date
* 27 October, 2001
*
* \author
* Stephan Wenger stewe@cs.tu-berlin.de
*****************************************************************************/
int RTPInterpretSliceHeader (byte *buf, int bufsize, int ReadSliceId, RTPSliceHeader_t *sh, struct img_par *img)
{
int len, info, bytes, dummy, bitptr=0;
int temp, tmp1;
RMPNIbuffer_t *tmp_rmpni,*tmp_rmpni2;
MMCObuffer_t *tmp_mmco,*tmp_mmco2;
int done;
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &sh->ParameterSet, &dummy);
bitptr+=len;
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &sh->structure, &dummy);
bitptr+=len;
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &sh->PictureID, &dummy);
bitptr+=len;
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &sh->SliceType, &dummy);
bitptr+=len;
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &sh->disposable_flag, &dummy);
bitptr+=len;
sh->num_ref_pic_active_fwd = 0;
sh->num_ref_pic_active_bwd = 0;
if(sh->SliceType==0 || sh->SliceType==2) // P or SP Picture
{
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &sh->num_ref_pic_active_fwd, &dummy);
bitptr+=len;
sh->num_ref_pic_active_fwd++;
}
else if(sh->SliceType==1) // B Picture
{
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &sh->num_ref_pic_active_fwd, &dummy);
bitptr+=len;
sh->num_ref_pic_active_fwd++;
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &sh->num_ref_pic_active_bwd, &dummy);
bitptr+=len;
sh->num_ref_pic_active_bwd++;
}
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &sh->FirstMBInSliceX, &dummy);
bitptr+=len;
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &sh->FirstMBInSliceY, &dummy);
bitptr+=len;
// JVT-D101
if(img->redundant_slice_flag)
{
len = GetfixedSymbol(buf, bitptr, &info, bufsize,1);
sh->redundant_pic_cnt = info;
bitptr+=len;
}
// End JVT-D101
if(sh->SliceType==1)
{
len = GetfixedSymbol(buf, bitptr, &info, bufsize,1);
sh->Direct_type = info;
bitptr+=len;
}
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo_dquant (len, info, &sh->InitialQP, &dummy);
bitptr+=len;
sh->InitialQP = sh->InitialQP + (MAX_QP - MIN_QP +1)/2;
if (sh->SliceType==2 || sh->SliceType==4) // SP Picture & SI Pictures
{
if(sh->SliceType==2) // Do not read for SI PICTURES
{
len = GetfixedSymbol(buf, bitptr, &info, bufsize,1);
sh->SwitchSP = info;
bitptr+=1;
}
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo_dquant (len, info, &sh->InitialSPQP, &dummy);
bitptr+=len;
sh->InitialSPQP = sh->InitialSPQP + (MAX_QP - MIN_QP +1)/2;
assert (sh->InitialSPQP >=MIN_QP && sh->InitialSPQP <= MAX_QP);
}
assert (sh->ParameterSet == 0); // only for testing, should be deleted as soon as more than one parameter set is generated by trhe encoder
assert (sh->SliceType > 0 || sh->SliceType < 5);
assert (sh->InitialQP >=MIN_QP && sh->InitialQP <= MAX_QP);
if (ParSet[CurrentParameterSet].FilterParametersFlag)
{
len = GetfixedSymbol(buf, bitptr, &info, bufsize,1);
sh->LFDisable = info;
bitptr+=1;
if (!sh->LFDisable)
{
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo_dquant (len, info, &sh->LFAlphaC0OffsetDiv2, &dummy);
bitptr+=len;
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo_dquant (len, info, &sh->LFBetaOffsetDiv2, &dummy);
bitptr+=len;
}
}
if (ReadSliceId)
{
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
linfo (len, info, &sh->SliceID, &dummy);
bitptr+=len;
}
/* KS: Multi-Picture Buffering Syntax */
/* Reference Picture Selection Flags */
len = GetVLCSymbol(buf, bitptr, &info, bufsize);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -