164 lines
3.9 KiB
C
164 lines
3.9 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/stat.h>
|
|
#include <string.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <netdb.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <fcntl.h>
|
|
#include <pthread.h>
|
|
#include <sched.h>
|
|
#include <sys/syscall.h>
|
|
#include <errno.h>
|
|
#include <sys/types.h>
|
|
#include <sys/mman.h>
|
|
|
|
|
|
|
|
|
|
|
|
#define NUM_NAL_BUF (3)
|
|
#define NAL_BUF_SIZE (512*1024)
|
|
#define VID_BUF_SIZE (512*1024)
|
|
typedef struct tnal_buf {
|
|
int len;
|
|
uint8_t *buf;
|
|
} nal_buf;
|
|
int fd_fs;
|
|
nal_buf nal_buf_entry[NUM_NAL_BUF];
|
|
|
|
unsigned char nal_header[4]={0x00,0x00,0x00,0x01};
|
|
|
|
void assemble_nal(unsigned char* buf, unsigned int len)
|
|
{
|
|
static int wr_idx = 0;
|
|
static int nalb_idx = 0;
|
|
uint64_t timestamp;
|
|
int need_sumbit, terminate;
|
|
if((wr_idx + len) >= VID_BUF_SIZE) {
|
|
printf("assemble_nal panic: too many error in pakts\r\n");
|
|
wr_idx = 0;
|
|
}
|
|
need_sumbit = 0;
|
|
terminate = 0;
|
|
|
|
|
|
if((!memcmp(buf, nal_header , 4)) && (len >= 4)) { //is seperator
|
|
if(wr_idx == 0) { // is new nal item
|
|
memcpy(nal_buf_entry[nalb_idx].buf + wr_idx, buf, len);
|
|
wr_idx += len;
|
|
}
|
|
else { //terminate current nal item and submit
|
|
need_sumbit = 1;
|
|
terminate = 1;
|
|
}
|
|
if(need_sumbit) {
|
|
nal_buf_entry[nalb_idx].len = wr_idx;
|
|
if(fd_fs)
|
|
write(fd_fs,nal_buf_entry[nalb_idx].buf,nal_buf_entry[nalb_idx].len);
|
|
wr_idx = 0;
|
|
nalb_idx = (nalb_idx+1)%NUM_NAL_BUF;
|
|
}
|
|
if(terminate) {
|
|
memcpy(nal_buf_entry[nalb_idx].buf + wr_idx, buf, len);
|
|
wr_idx += len;
|
|
}
|
|
}else {
|
|
memcpy(nal_buf_entry[nalb_idx].buf + wr_idx, buf, len);
|
|
wr_idx += len;
|
|
if(memcmp(nal_buf_entry[nalb_idx].buf, nal_header, 4)) { //wait nal head
|
|
wr_idx = 0;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int socket_descriptor;
|
|
int i;
|
|
int len;
|
|
char buffer_nal[2048];
|
|
struct timeval tv;
|
|
|
|
|
|
struct sockaddr_in address;
|
|
struct sockaddr_in clientAddr;
|
|
|
|
|
|
len = sizeof(clientAddr);
|
|
|
|
bzero(&address,sizeof(address));
|
|
address.sin_family=AF_INET;
|
|
address.sin_addr.s_addr=htonl(INADDR_ANY);
|
|
address.sin_port=htons(20000);
|
|
|
|
socket_descriptor=socket(AF_INET,SOCK_DGRAM,0);//IPV4
|
|
|
|
tv.tv_sec = 1;
|
|
tv.tv_usec = 0;
|
|
if (setsockopt(socket_descriptor, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
|
|
printf("socket option SO_RCVTIMEO not support\n");
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
if (bind(socket_descriptor, (struct sockaddr *)&address, sizeof(address)) < 0)
|
|
{
|
|
perror("bind");
|
|
exit(1);
|
|
}
|
|
|
|
|
|
|
|
if(argc == 2){
|
|
|
|
fd_fs = open(argv[1], O_RDWR | O_CREAT);
|
|
if(fd_fs < 0) {
|
|
printf("open %s failed\n", argv[1]);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
for(i=0; i<NUM_NAL_BUF; i++) {
|
|
nal_buf_entry[i].buf = (uint8_t *) malloc(NAL_BUF_SIZE);
|
|
if(!nal_buf_entry[i].buf) {
|
|
printf("allocate nal buf failed\r\n");
|
|
return -1;
|
|
}
|
|
memset(nal_buf_entry[i].buf, 0x0, NAL_BUF_SIZE);
|
|
}
|
|
|
|
#if 0
|
|
|
|
pthread_mutex_init(&pkts_mutex, NULL);
|
|
pthread_cond_init(&pkts_cond, NULL);
|
|
pthread_attr_init(&attr);
|
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
|
len = pthread_create(&pkts_thread, &attr, pkts_worker, NULL);
|
|
pthread_attr_destroy(&attr);
|
|
pkts_q = dq_create();
|
|
#endif
|
|
while(1)
|
|
{
|
|
|
|
i = recvfrom(socket_descriptor, buffer_nal, 1472, 0, (struct sockaddr*)&clientAddr, &len);
|
|
|
|
if(i>0)
|
|
assemble_nal(buffer_nal,i);
|
|
|
|
}
|
|
close(socket_descriptor);
|
|
printf("send file finish\r\n");
|
|
}
|
|
|
|
|