#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#define UINT16 unsigned short
#define UINT32 unsigned int
#define RTPHEAD_LEN 12
typedef struct {
UINT16 rtpVersion : 2; /* Version Of RTP */
UINT16 paddingBit : 1; /* Padding Bit of Packet */
UINT16 extensionBit : 1; /* Extension Bit of Packet */
UINT16 csrcCount : 4; /* CSRC Count of Packet */
UINT16 markerBit : 1; /* Marker Bit of Packet */
UINT16 payloadType : 7; /* Payload Type of Packet */
UINT16 sequenceNumber; /* Sequence number of packet */
UINT32 timestamp; /* Time Stamp of packet */
UINT32 ssrc; /* SSRC of packet */
UINT32 csrc[16]; /* CSRC List */
}RTPHead;
int find_nextrtphead(char *buf, int len, RTPHead *rtphead)
{
int i = 0;
UINT16 seq;
int lendata = len - RTPHEAD_LEN;
for(i = 0; i < lendata; i++)
{
if((buf[i] == (char)0x80) && (buf[i+1] == (char)0x60 || buf[i+1] == (char)0xe0))
{
//seq = (UINT16)((buf[i+2] << 8) | buf[i+3]);
seq = (unsigned char)buf[i+2];
seq = seq << 8;
seq += (unsigned char)buf[i+3];
if(seq == (rtphead->sequenceNumber + 1))
return i;
}
}
return -1;
}
int parseRTPHeader(char *buf, RTPHead *rtphead)
{
UINT16 seq;
seq = (unsigned char)buf[2];
seq = seq << 8;
seq += (unsigned char)buf[3];
rtphead->sequenceNumber = seq;
printf("SEQ:%d.\n", rtphead->sequenceNumber);
return 0;
}
int sendrtpdata(int sock, struct sockaddr_in *destaddr, char *buf, int len)
{
return sendto(sock, buf, len, 0, (struct sockaddr *)destaddr, sizeof(struct sockaddr));
}
int main()
{
int fd = -1;
int vsock = -1;
int asock = -1;
char readbuf[1024 * 16];
int readn = 0;
int datalen = 0;
struct sockaddr_in destaddr;
struct sockaddr_in destaddr1;
FILE *h264file = NULL;
RTPHead rtphead;
fd = open("test.rtp", O_RDONLY);
if(fd < 0)
{
perror("open file failed:");
return -1;
}
vsock = socket(AF_INET, SOCK_DGRAM, 0);
if(vsock < 0)
{
perror("open vsock failed:");
return -1;
}
asock = socket(AF_INET, SOCK_DGRAM, 0);
if(asock < 0)
{
perror("open asock failed:");
return -1;
}
h264file = fopen("rec.h264", "wb");
if(h264file == NULL)
{
perror("open rec file failed:");
return -1;
}
destaddr.sin_family = AF_INET;
destaddr.sin_addr.s_addr = inet_addr("192.168.0.12");
destaddr.sin_port = htons(9712);
destaddr1.sin_family = AF_INET;
destaddr1.sin_addr.s_addr = inet_addr("225.1.1.12");
destaddr1.sin_port = htons(9712);
while(1)
{
readn = read(fd, readbuf+datalen, sizeof(readbuf)-datalen);
if(readn != (sizeof(readbuf)-datalen))
{
break;
}
else
{
int nextpos = 0;
int curpos = 0;
datalen += readn;
while(1)
{
if(datalen < 1600)
{
memmove(readbuf, readbuf+curpos, datalen);
break;
}
parseRTPHeader(readbuf+curpos, &rtphead);
nextpos = find_nextrtphead(readbuf+curpos+RTPHEAD_LEN, datalen-RTPHEAD_LEN, &rtphead);
if(nextpos >= 0)
{
sendrtpdata(vsock, &destaddr, readbuf+curpos, nextpos+RTPHEAD_LEN);
sendrtpdata(vsock, &destaddr1, readbuf+curpos, nextpos+RTPHEAD_LEN);
fwrite(readbuf+curpos+RTPHEAD_LEN, 1, nextpos, h264file);
curpos += RTPHEAD_LEN;
datalen -= RTPHEAD_LEN;
curpos += nextpos;
datalen -= nextpos;
usleep(1000);
continue;
}
else
{
printf("data error.abort\n");
return -1;
}
}
}
}
return 0;
}
评论