00001
00089 #ifdef WIN32
00090 #include <Winsock2.h>
00091 #else
00092 #include <netinet/in.h>
00093 #endif
00094
00095 #include "contributors.h"
00096 #include "global.h"
00097 #include "errorconcealment.h"
00098 #include "rtp.h"
00099 #include "fmo.h"
00100 #include "sei.h"
00101 #include "memalloc.h"
00102
00103 static int BitStreamFile;
00104
00105 int RTPReadPacket (RTPpacket_t *p, int bitstream);
00106
00115 void OpenRTPFile (char *fn)
00116 {
00117 if ((BitStreamFile = open(fn, OPENFLAGS_READ)) == -1)
00118 {
00119 snprintf (errortext, ET_SIZE, "Cannot open RTP file '%s'", fn);
00120 error(errortext,500);
00121 }
00122 }
00123
00124
00131 void CloseRTPFile(void)
00132 {
00133 if (BitStreamFile != -1)
00134 {
00135 close(BitStreamFile);
00136 BitStreamFile = - 1;
00137 }
00138 }
00139
00140
00156 int GetRTPNALU (NALU_t *nalu)
00157 {
00158 static unsigned short first_call = 1;
00159 static unsigned short old_seq = 0;
00160
00161 RTPpacket_t *p;
00162 int ret;
00163
00164 if ((p=malloc (sizeof (RTPpacket_t)))== NULL)
00165 no_mem_exit ("GetRTPNALU-1");
00166 if ((p->packet=malloc (MAXRTPPACKETSIZE))== NULL)
00167 no_mem_exit ("GetRTPNALU-2");
00168 if ((p->payload=malloc (MAXRTPPACKETSIZE))== NULL)
00169 no_mem_exit ("GetRTPNALU-3");
00170
00171 ret = RTPReadPacket (p, BitStreamFile);
00172 nalu->forbidden_bit = 1;
00173 nalu->len = 0;
00174
00175 if (ret > 0)
00176 {
00177 if (first_call)
00178 {
00179 first_call = 0;
00180 old_seq = (unsigned short) (p->seq - 1);
00181 }
00182
00183 nalu->lost_packets = (unsigned short) ( p->seq - (old_seq + 1) );
00184 old_seq = p->seq;
00185
00186 assert (p->paylen < nalu->max_size);
00187
00188 nalu->len = p->paylen;
00189 memcpy (nalu->buf, p->payload, p->paylen);
00190 nalu->forbidden_bit = (nalu->buf[0]>>7) & 1;
00191 nalu->nal_reference_idc = (nalu->buf[0]>>5) & 3;
00192 nalu->nal_unit_type = (nalu->buf[0]) & 0x1f;
00193 if (nalu->lost_packets)
00194 {
00195 printf ("Warning: RTP sequence number discontinuity detected\n");
00196 }
00197 }
00198
00199
00200 free (p->payload);
00201 free (p->packet);
00202 free (p);
00203
00204
00205
00206 if (ret>0)
00207
00208 return nalu->len;
00209 else
00210
00211 return ret;
00212 }
00213
00214
00215
00241 int DecomposeRTPpacket (RTPpacket_t *p)
00242
00243 {
00244
00245 assert (p->packlen < 65536 - 28);
00246 assert (p->packlen >= 12);
00247 assert (p->payload != NULL);
00248 assert (p->packet != NULL);
00249
00250
00251
00252 p->v = (p->packet[0] >> 6) & 0x03;
00253 p->p = (p->packet[0] >> 5) & 0x01;
00254 p->x = (p->packet[0] >> 4) & 0x01;
00255 p->cc = (p->packet[0] >> 0) & 0x0F;
00256
00257 p->m = (p->packet[1] >> 7) & 0x01;
00258 p->pt = (p->packet[1] >> 0) & 0x7F;
00259
00260 memcpy (&p->seq, &p->packet[2], 2);
00261 p->seq = ntohs((unsigned short)p->seq);
00262
00263 memcpy (&p->timestamp, &p->packet[4], 4);
00264 p->timestamp = ntohl(p->timestamp);
00265 memcpy (&p->ssrc, &p->packet[8], 4);
00266 p->ssrc = ntohl(p->ssrc);
00267
00268
00269 if ( (p->v != 2)
00270 || (p->p != 0)
00271 || (p->x != 0)
00272 || (p->cc != 0) )
00273 {
00274 printf ("DecomposeRTPpacket, RTP header consistency problem, header follows\n");
00275 DumpRTPHeader (p);
00276 return -1;
00277 }
00278 p->paylen = p->packlen-12;
00279 memcpy (p->payload, &p->packet[12], p->paylen);
00280 return 0;
00281 }
00282
00305 void DumpRTPHeader (RTPpacket_t *p)
00306
00307 {
00308 int i;
00309 for (i=0; i< 30; i++)
00310 printf ("%02x ", p->packet[i]);
00311 printf ("Version (V): %d\n", (int) p->v);
00312 printf ("Padding (P): %d\n", (int) p->p);
00313 printf ("Extension (X): %d\n", (int) p->x);
00314 printf ("CSRC count (CC): %d\n", (int) p->cc);
00315 printf ("Marker bit (M): %d\n", (int) p->m);
00316 printf ("Payload Type (PT): %d\n", (int) p->pt);
00317 printf ("Sequence Number: %d\n", (int) p->seq);
00318 printf ("Timestamp: %d\n", (int) p->timestamp);
00319 printf ("SSRC: %d\n", (int) p->ssrc);
00320 }
00321
00322
00350 int RTPReadPacket (RTPpacket_t *p, int bitstream)
00351 {
00352 int64 Filepos;
00353 int intime;
00354
00355 assert (p != NULL);
00356 assert (p->packet != NULL);
00357 assert (p->payload != NULL);
00358
00359 Filepos = tell (bitstream);
00360 if (4 != read (bitstream, &p->packlen, 4))
00361 {
00362 return 0;
00363 }
00364 if (4 != read (bitstream, &intime, 4))
00365 {
00366 lseek (bitstream, Filepos, SEEK_SET);
00367 printf ("RTPReadPacket: File corruption, could not read Timestamp, exit\n");
00368 exit (-1);
00369 }
00370
00371 assert (p->packlen < MAXRTPPACKETSIZE);
00372
00373 if (p->packlen != read (bitstream, p->packet, p->packlen))
00374 {
00375 printf ("RTPReadPacket: File corruption, could not read %d bytes\n", (int) p->packlen);
00376 exit (-1);
00377 }
00378
00379 if (DecomposeRTPpacket (p) < 0)
00380 {
00381
00382
00383 printf ("Errors reported by DecomposePacket(), exit\n");
00384 exit (-700);
00385 }
00386 assert (p->pt == H264PAYLOADTYPE);
00387 assert (p->ssrc == H264SSRC);
00388 return p->packlen;
00389 }
00390