📄 rtp.c
字号:
if (!strncmp (s, "MotionResolution", MAX_PARAMETER_STRINGLEN))
{
state = EXPECT_STRUCTVAL_STRING;
interpreter = INTERPRET_MOTION_RESOLUTION;
destin = &ParSet[ps].MotionResolution;
break;
}
if (!strncmp (s, "PartitioningType", MAX_PARAMETER_STRINGLEN))
{
state = EXPECT_STRUCTVAL_STRING;
interpreter = INTERPRET_PARTITIONING_TYPE;
destin = &ParSet[ps].PartitioningType;
break;
}
if (!strncmp (s, "IntraPredictionType", MAX_PARAMETER_STRINGLEN))
{
state = EXPECT_STRUCTVAL_STRING;
interpreter = INTERPRET_INTRA_PREDICTION;
destin = &ParSet[ps].IntraPredictionType;
break;
}
if (!strncmp (s, "HRCParameters", MAX_PARAMETER_STRINGLEN))
{
state = EXPECT_STRUCTVAL_INT;
interpreter = INTERPRET_COPY;
destin = &ParSet[ps].HRCParameters;
break;
}
if (!strncmp (s, "FramesToBeEncoded", MAX_PARAMETER_STRINGLEN))
{
state = EXPECT_STRUCTVAL_INT;
interpreter = INTERPRET_COPY;
destin = &InfoSet.FramesToBeEncoded;
break;
}
if (!strncmp (s, "FrameSkip", MAX_PARAMETER_STRINGLEN))
{
state = EXPECT_STRUCTVAL_INT;
interpreter = INTERPRET_COPY;
destin = &InfoSet.FrameSkip;
break;
}
if (!strncmp (s, "SequenceFileName", MAX_PARAMETER_STRINGLEN))
{
state = EXPECT_STRUCTVAL_STRING;
interpreter = INTERPRET_COPY;
destin = &InfoSet.SequenceFileName;
break;
}
if (!strncmp (s, "NumberBFrames", MAX_PARAMETER_STRINGLEN))
{
state = EXPECT_STRUCTVAL_INT;
interpreter = INTERPRET_COPY;
destin = &InfoSet.NumberBFrames;
break;
}
// Here, all defined Parameter names are checked. Anything else is a syntax error
printf ("Syntax Error: unknown Parameter %s\n", s);
printf ("Parsing error in Header Packet: position %d, packet %s\n",
bufp, buf);
return -3;
break; // to make lint happy
case EXPECT_STRUCTVAL_INT:
if (1!=sscanf (&buf[bufp], "%d", (int *)destin))
{
printf ("Parsing error EXPECT STRUCTVAL INT in Header Packet: position %d, packet %s\n",
bufp, &buf[bufp]);
return -4;
}
// printf ("EXPECT_STRCUTVAL_INT: write %d\n", * (int *)destin);
while (bufp < buflen && buf[bufp] != '\n') // Skip any trailing whitespace and \n
bufp++;
bufp++;
state=EXPECT_ATTR;
break;
case EXPECT_STRUCTVAL_STRING:
if (1 != sscanf (&buf[bufp], "%100s", s))
{
printf ("Parsing error EXPECT STRUCTVAL STRING in Header Packet: position %d, packet %s\n",
bufp, &buf[bufp]);
return -5;
}
while (bufp < buflen && buf[bufp] != '\n') // Skip any trailing whitespace and \n
bufp++;
bufp++;
state=EXPECT_ATTR;
switch (interpreter)
{
case INTERPRET_COPY:
// nothing -- handled where it occurs
break;
case INTERPRET_ENTROPY_CODING:
if (!strncmp (s, "UVLC", 4))
* (int *)destin = 0;
else
* (int *)destin = 1;
// printf ("in INterpret, Entropy COding :%s: results in %d\n", s, *(int *)destin);
break;
case INTERPRET_MOTION_RESOLUTION:
if (!strncmp (s, "quater", 6))
* (int *)destin = 0;
else
* (int *)destin = 1;
break;
case INTERPRET_INTRA_PREDICTION:
if (!strncmp (s, "InterPredicted", 14))
* (int *)destin = 0;
else
* (int *)destin = 1;
break;
case INTERPRET_PARTITIONING_TYPE:
if (!strncmp (s, "one", 3))
* (int *)destin = 0;
else
* (int *)destin = 1;
break;
default:
assert (0==1);
}
break;
default:
printf ("Parsing error UNDEFINED SYNTAX in Header Packet: position %d, packet %s\n",
bufp, &buf[bufp]);
return -1;
}
// printf ("\t\t%d\n", bufp);
}
// printf ("CurrentParameterSet %d, ps %d\n", CurrentParameterSet, ps);
// printf ("RTPInterpretParameterPacket: xsize x Ysize, %d x %d, Entropy %d, Motion %d MaxPicId %d\n",
// ParSet[ps].XSizeMB, ParSet[ps].YSizeMB, ParSet[ps].EntropyCoding, ParSet[ps].MotionResolution, ParSet[ps].MaxPicID);
ParSet[ps].Valid = 1;
return 0;
}
/*!
************************************************************************
* \brief
* Update img->xxx with the content of a parameter set, called for
* every slice
************************************************************************
*/
void RTPUseParameterSet (int n, struct img_par *img, struct inp_par *inp)
{
int status;
if (n == CurrentParameterSet)
return; // no change
// printf ("Use a new parameter set: old %d, new %d\n", CurrentParameterSet, n);
CurrentParameterSet = n;
status = RTP_PARAMETER_SET_OK;
if (CurrentParameterSet < 0 || (CurrentParameterSet > RTP_MAX_PARAMETER_SET))
{
printf ("Parameter Set %d out of range, conceal to 0\n", CurrentParameterSet);
CurrentParameterSet = 0; // and pray that it works...
status = RTP_PARAMETER_SET_OUT_OF_RANGE;
}
if (!ParSet[CurrentParameterSet].Valid)
{
printf ("Try to use uninitialized Parameter Set %d, conceal to 0\n", CurrentParameterSet);
CurrentParameterSet = 0;
status = RTP_PARAMETER_SET_INVALID;
}
// Now updates global decoder variables with the appropriate parameter set.
// A full-fledged decoder would make some consistency checks. For example,
// it makes sense to change the MotionResolution or the EntropyCode within
// a picture (img->current_mb_nr != 0). It doesn't make sense to change
// the pixel aspect ratio.
// There is no need to do those checks in an error free environment -- an
// encoder is simply not supposed to do so. In error prone environments,
// however, this is an additional means for error detection.
// Note: Many parameters are available in both the input-> and img-> structures.
// Some people seem to use the input-> parameters, others the img-> parameters.
// This should be cleaned up one day.
// For now simply copy any updated variables into both structures.
// MaxPicID: doesn't exist in pinput-> or img->
inp->buf_cycle = ParSet[CurrentParameterSet].BufCycle;
img->buf_cycle = inp->buf_cycle+1; // see init_global_buffers()
// PixAspectRatioX: doesn't exist
// PixAspectRatioY: doesn't exist
// DisplayWindowOffset*: doesn't exist
// XSizeMB
img->width = ParSet[CurrentParameterSet].XSizeMB*16;
img->width_cr = ParSet[CurrentParameterSet].XSizeMB*8;
//YSizeMB
img->height = ParSet[CurrentParameterSet].YSizeMB*16;
img->height_cr = ParSet[CurrentParameterSet].YSizeMB*8;
// EntropyCoding
if (ParSet[CurrentParameterSet].EntropyCoding == 0)
inp->symbol_mode = UVLC;
else
inp->symbol_mode = CABAC;
// MotionResolution
img->mv_res = ParSet[CurrentParameterSet].MotionResolution;
// PartitioningType
inp->partition_mode = ParSet[CurrentParameterSet].PartitioningType;
// IntraPredictionType
inp->UseConstrainedIntraPred = ParSet[CurrentParameterSet].IntraPredictionType;
//! img->type: This is calculated by using ParSet[CurrentParameterSet].UseMultpred
//! and the slice type from the slice header. It is set in RTPSetImgInp()
// HRCParameters: Doesn't exist
}
/*!
*****************************************************************************
*
* \brief
* RTPReadPacket reads one packet from file
*
* \return
* 0 in case of success, -1 in case of error
*
* \para Paremeters
* p: packet data structure, with memory for p->packet allocated
*
* Side effects:
* - File pointer in bits moved
* - p->xxx filled by reading and Decomposepacket()
*
* \date
* 04 November, 2001
*
* \author
* Stephan Wenger, stewe@cs.tu-berlin.de
*****************************************************************************/
int RTPReadPacket (RTPpacket_t *p, FILE *bits)
{
int Filepos, intime;
assert (p != NULL);
assert (p->packet != NULL);
assert (p->payload != NULL);
Filepos = ftell (bits);
if (4 != fread (&p->packlen,1, 4, bits))
{
printf ("Unable to read 4 bytes for the RTP packet size\n");
fseek (bits, Filepos, SEEK_SET);
return -1;
}
if (4 != fread (&intime, 1, 4, bits))
{
fseek (bits, Filepos, SEEK_SET);
printf ("RTPReadPacket: File corruption, could not read Timestamp, exit\n");
exit (-1);
}
assert (p->packlen < MAXRTPPACKETSIZE);
if (p->packlen != fread (p->packet, 1, p->packlen, bits))
{
printf ("RTPReadPacket: File corruption, could not read %d bytes\n", p->packlen);
exit (-1); // EOF inidication
}
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);
}
assert (p->pt == H26LPAYLOADTYPE);
assert (p->ssrc == 0x12345678);
return 0;
}
/*!
*****************************************************************************
*
* \brief
* RTPReadDataPartitionedSlice collects all partitiobnss of the slice
*
*
* \return
* sequence number of the last packed that has been concealed
*
* VCEG-N72r1 may not state it explicitely, but we decided that partitions
* have to be sent immediately after each other. Meaning, if A, B, and C are
* all present, the rtp-timestamp of A is 2 bigger than the one of A.
* Hence, this function reads all those partitions into their respective
* buffers
*
* Side effects: many!
* - File pointer in bits moved
* - currSlice->partArr[0, 1, 2] updated
* - img-> and inp-> updated, see RTPSetImgInp()
*
* \date
* 04 November, 2001
*
* \author
* Stephan Wenger, stewe@cs.tu-berlin.de
*****************************************************************************/
#define SEQ_PLUS_1 (a->seq+1 == b->seq)
#define SEQ_PLUS_2 (a->seq+2 == b->seq)
#define SAME_TIME (a->timestamp == b->timestamp)
#define SLICE_NO_OK (b_SliceID == a_SliceID)
#define SAME_SLICE (SAME_TIME && SLICE_NO_OK)
#define TYPE_B (b->payload[0] == 2)
#define TYPE_C (b->payload[0] == 3)
void RTPProcessDataPartitionedSlice (struct img_par *img, struct inp_par *inp, FILE *bits,
RTPpacket_t *a, int a_SliceID)
{
//! BUG: need to fix wrap-around-problem for the sequence number
//! needs to be fixed only for HUGE files (more than 2^^16 packets)
//! Note: in contrast to RTP spec, encoder starts sequence no at 0 to ease debugging
RTPpacket_t *b, *c;
RTPSliceHeader_t *sh;
long Filepos;
int StartMBData;
int b_SliceID, b_PicId, c_SliceID, c_PicID;
Slice *currSlice = img->currentSlice;
Filepos = ftell (bits);
b=alloca(sizeof(RTPpacket_t));
b->packet=alloca (MAXRTPPACKETSIZE);
b->payload=alloca (MAXRTPPAYLOADLEN);
sh=alloca (sizeof(RTPSliceHeader_t));
free_Partition (currSlice->partArr[1].bitstream);
free_Partition (currSlice->partArr[2].bitstream);
if (RTPReadPacket (b, bits) != 0)
{
printf ("Error while reading RTP packet, assuming intentional EOF and the last slice contains no type B, C\n");
img->currentSlice->partArr[1].bitstream->bitstream_length=0;
img->currentSlice->partArr[1].bitstream->code_len=0;
img->currentSlice->partArr[1].bitstream->ei_flag=0;
img->currentSlice->partArr[2].bitstream->bitstream_length=0;
img->currentSlice->partArr[2].bitstream->code_len=0;
img->currentSlice->partArr[2].bitstream->ei_flag=0;
return;
}
StartMBData = RTPInterpretPartitionHeader (&b->payload[1], b->paylen, sh);
//StartMBData++; // Skip First Byte
b_SliceID = sh->SliceID;
b_PicId = sh->PictureID;
// General:
// Lost partition, identified by missing packet due to sequence number problems, or
// Empty partition, identified by not present partition
// The two cases are signalled to higher layers as follows
// Lost Partition: currStream->ei_flag is set, length inidicators don't care
// Empty Partition: only length indicator is zero, ei_flag is cleared
if (b->seq > a->seq+2) // two or more consecutive packet losses, none, one, or both
{ // partitions lost and no way to figure which ones
fseek (bits, Filepos, SEEK_SET); // go back
printf ("lost at least two partitions\n");
img->currentSlice->partArr[1].bitstream->bitstream_length=0;
img->currentSlice->partArr[1].bitstream->code_len=0;
img->currentSlice->partArr[1].bitstream->ei_flag=1;
img->currentSlice->partArr[1].readSyntaxElement = readSyntaxElement_RTP;
img->currentSlice->partArr[2].bitstream->bitstream_length=0;
img->currentSlice->partArr[2].bitstream->code_len=0;
img->currentSlice->partArr[2].bitstream->ei_flag=1;
img->currentSlice->partArr[2].readSyntaxElement = readSyntaxElement_RTP;
return;
}
if (SEQ_PLUS_2 && !SAME_SLICE) // one packet was lost could be type B partition or type C partition
{
fseek (bits, Filepos,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -