#include "h264.h"
FILE * pinfile = NULL;
char * inputfilename = "..\\H264_STREAM\\sender.264";
int InitiateWinsock()
{
int Error;
WORD Version=MAKEWORD(2,2);
WSADATA WsaData;
Error=WSAStartup(Version,&WsaData); //Start up WSA
if(Error!=0)
return 0;
else
{
if(LOBYTE(WsaData.wVersion)!=2||HIBYTE(WsaData.wHighVersion)!=2)
{
WSACleanup();
return 0;
}
}
return 1;
}
NALU_t *AllocNALU(int buffersize)
{
NALU_t *n;
if ((n = (NALU_t*)calloc (1, sizeof(NALU_t))) == NULL)
{
printf("AllocNALU Error: Allocate Meory To NALU_t Failed ");
exit(0);
}
n->max_size=buffersize; //Assign buffer size
if ((n->buf = (char*)calloc (buffersize, sizeof (char))) == NULL)
{
free (n);
printf ("AllocNALU Error: Allocate Meory To NALU_t Buffer Failed ");
exit(0);
}
return n;
}
void FreeNALU(NALU_t *n)
{
if (n)
{
if (n->buf)
{
free(n->buf);
n->buf=NULL;
}
free (n);
}
}
int OpenBitstreamFile (char *fn)
{
if (NULL == (pinfile = fopen(fn, "rb")))
{
printf("Error: Open input file error\n");
getchar();
}
return 1;
}
static int FindStartCode2 (unsigned char *Buf)
{
if(Buf[0]!=0 || Buf[1]!=0 || Buf[2] !=1) //Check whether buf is 0x000001
{
return 0;
}
else
{
return 1;
}
}
static int FindStartCode3 (unsigned char *Buf)
{
if(Buf[0]!=0 || Buf[1]!=0 || Buf[2] !=0 || Buf[3] !=1) //Check whether buf is 0x00000001
{
return 0;
}
else
{
return 1;
}
}
int GetAnnexbNALU (NALU_t *nalu)
{
int pos = 0; //一个nal到下一个nal 数据移动的指针
int StartCodeFound = 0; //是否找到下一个nal 的前缀
int rewind = 0; //判断 前缀所占字节数 3或 4
unsigned char * Buf = NULL;
static int info2 =0 ;
static int info3 =0 ;
if ((Buf = (unsigned char*)calloc (nalu->max_size , sizeof(char))) == NULL)
{
printf ("GetAnnexbNALU Error: Could not allocate Buf memory\n");
}
nalu->startcodeprefix_len = 3; //初始化前缀位三个字节
if (3 != fread (Buf, 1, 3, pinfile))//从文件读取三个字节到buf
{
free(Buf);
return 0;
}
info2 = FindStartCode2 (Buf); //Check whether Buf is 0x000001
if(info2 != 1)
{
//If Buf is not 0x000001,then read one more byte
if(1 != fread(Buf+3, 1, 1, pinfile))
{
free(Buf);
return 0;
}
info3 = FindStartCode3 (Buf); //Check whether Buf is 0x00000001
if (info3 != 1) //If not the return -1
{
free(Buf);
return -1;
}
else
{
//If Buf is 0x00000001,set the prefix length to 4 bytes
pos = 4;
nalu->startcodeprefix_len = 4;
}
}
else
{
//If Buf is 0x000001,set the prefix length to 3 bytes
pos = 3;
nalu->startcodeprefix_len = 3;
}
//寻找下一个字符符号位, 即 寻找一个nal 从一个0000001 到下一个00000001
StartCodeFound = 0;
info2 = 0;
info3 = 0;
while (!StartCodeFound)
{
if (feof (pinfile)) //如果到了文件结尾
{
nalu->len = (pos-1) - nalu->startcodeprefix_len; //从0 开始
memcpy (nalu->buf, &Buf[nalu->startcodeprefix_len], nalu->len);
nalu->forbidden_bit = nalu->buf[0] & 0x80; // 1 bit--10000000
nalu->nal_reference_idc = nalu->buf[0] & 0x60; // 2 bit--01100000
nalu->nal_unit_type = (nalu->buf[0]) & 0x1f; // 5 bit--00011111
free(Buf);
return pos-1;
}
Buf[pos++] = fgetc (pinfile); //Read one char to the Buffer 一个字节一个字节从文件向后找
info3 = FindStartCode3(&Buf[pos-4]); //Check whether Buf is 0x00000001
if(info3 != 1)
{
info2 = FindStartCode2(&Buf[pos-3]); //Check whether Buf is 0x000001
}
StartCodeFound = (info2 == 1 || info3 == 1); //如果找到下一个前缀
}
rewind = (info3 == 1)? -4 : -3;
if (0 != fseek (pinfile, rewind, SEEK_CUR)) //将文件内部指针移动到 nal 的末尾
{
free(Buf);
printf("GetAnnexbNALU Error: Cannot fseek in the bit stream file");
}
nalu->len = (pos + rewind) - nalu->startcodeprefix_len; //设置包含nal 头的数据长度
memcpy (nalu->buf, &Buf[nalu->startcodeprefix_len], nalu->len);//拷贝一个nal 数据到数组中
nalu->forbidden_bit = nalu->buf[0] & 0x80; //1 bit 设置nal 头
nalu->nal_reference_idc = nalu->buf[0] & 0x60; // 2 bit
nalu->nal_unit_type = (nalu->buf[0]) & 0x1f; // 5 bit
free(Buf);
return (pos + rewind); //Return the length of bytes from between one NALU and the next NALU
}
int main()
{
SOCKET socket_cli;
SOCKADDR_IN addrser;//Initialize Win Socket
NALU_t * n = NULL;
unsigned char sendbuf[MAXDATASIZE];
RTP_HEADER * rtp_hdr = NULL ;
int pocket_number = 0; //包号
int frame_number = 0; //帧号
int total_sent = 0; //已经发送的总共数据
NALU_HEADER * nalu_hdr = NULL;
char* nalu_payload = NULL;
int bytes = 0; //一次发送的数据
int timestamp = 0;
FU_INDICATOR *fu_ind = NULL ;
FU_HEADER *fu_hdr = NULL ;
InitiateWinsock();
//创建socket套接字
socket_cli= socket(AF_INET ,SOCK_DGRAM/*UDP协议的是流式*/,0);
addrser.sin_addr.S_un.S_addr =inet_addr(USE_IP);
addrser.sin_family = AF_INET;
addrser.sin_port = htons(USE_PORT); //网络字节序
OpenBitstreamFile(inputfilename); //打开本地要传输的文件
n = AllocNALU(8000000); //分配nal 资源
while(!feof(pinfile)) //如果未到文件结尾
{
GetAnnexbNALU(n);
printf("NALU--- forbidden_bit : %d\n", n->forbidden_bit);
printf("NALU--- nal_reference_idc : %d\n", n->nal_reference_idc);
printf("NALU--- Type : %d\n", n->nal_unit_type);
printf("NALU--- startcodeprefix_len : %d\n", n->startcodeprefix_len);
printf("NALU--- len : %d\n", n->len);
printf("NALU--- max_size : %d\n", n->max_size);
memset(sendbuf,0,MAXDATASIZE);
rtp_hdr =(RTP_HEADER*)&sendbuf[0];
rtp_hdr->payloadtype = H264; //Payload type
rtp_hdr->version = 2; //Payload version
rtp_hdr->marker = 0; //Marker sign
rtp_hdr->ssrc = htonl(frame_number++); //帧数
if (n->len < 1400) //打单包
{
rtp_hdr->marker = 1;
rtp_hdr->seq_no = htons(pocket_number ++);
nalu_hdr =(NALU_HEADER*)&sendbuf[12];
nalu_hdr->F = n->forbidden_bit >> 7;
nalu_hdr->NRI = n->nal_reference_idc >> 5;
nalu_hdr->TYPE = n->nal_unit_type;
nalu_payload = &sendbuf[13];
memcpy(nalu_payload,n->buf+1,n->len-1);
timestamp = timestamp + 6000;
rtp_hdr->timestamp = htonl(timestamp);
bytes = n->len + 12 ;
Sleep(40);
sendto(socket_cli,sendbuf,bytes,0,(SOCKADDR *)&addrser,sizeof(SOCKADDR));
total_sent += bytes;
printf("单包:Total bytes : %d\n",bytes);
printf("Total bytes sent : %d\n",total_sent);
}
else if (n->len >= 1400) //打分片包
{
int k=0;
int l=0;
int t = 0; //分片包片号
k = n->len / 1400; //分片数目
l = n->len % 1400; //最后一个包的长度
timestamp = timestamp + 6000;
rtp_hdr->timestamp = htonl(timestamp);
while(t <= k)
{
rtp_hdr->seq_no = htons(pocket_number ++); //包号
if(!t) //分片打包第一个分片
{
rtp_hdr->marker = 0;
fu_ind =(FU_INDICATOR*)&sendbuf[12];
fu_ind->F=n->forbidden_bit >> 7;
fu_ind->NRI=n->nal_reference_idc>>5;
fu_ind->TYPE=28;
fu_hdr =(FU_HEADER*)&sendbuf[13];
fu_hdr->E=0;
没有合适的资源?快使用搜索试试~ 我知道了~
H264编解码并打包为rtp发送
共69个文件
tlog:18个
gif:4个
user:4个
4星 · 超过85%的资源 需积分: 50 51 下载量 181 浏览量
2013-04-18
13:54:27
上传
评论 2
收藏 15.21MB RAR 举报
温馨提示
发送端对H264编码的视屏文件进行rtp打包发送至接收端,接收端在进行逆向rtp组包,并保存为本地文件,C/S结构
资源推荐
资源详情
资源评论
收起资源包目录
H264rtp.rar (69个子文件)
recieve
h264.h 5KB
receive
ipch
receive-d134ba1f
receive-352812cf.ipch 31.81MB
H264_STREAM
receive.264 2.81MB
receive.ncb 6.44MB
receive
Debug
cl.command.1.tlog 490B
CL.read.1.tlog 13KB
mt.read.1.tlog 818B
link.read.1.tlog 2KB
link.write.1.tlog 434B
BuildLog.htm 8KB
mt.dep 67B
CL.write.1.tlog 348B
vc100.pdb 68KB
main.obj 38KB
receive.log 2KB
link.command.1.tlog 1KB
receive.lastbuildstate 68B
mt.write.1.tlog 304B
mt.command.1.tlog 480B
vc80.idb 123KB
receive.exe.intermediate.manifest 381B
receive.vcxproj 3KB
receive.vcproj 3KB
receive.vcxproj.filters 1KB
receive.vcxproj.user 143B
receive.vcproj.PC-200909201114.Administrator.user 1KB
debug
receive.exe 10KB
_UpgradeReport_Files
UpgradeReport.xslt 12KB
UpgradeReport_Plus.gif 71B
UpgradeReport.css 3KB
UpgradeReport_Minus.gif 69B
UpgradeLog.XML 2KB
receive.suo 7KB
receive.sln 888B
main.c 9KB
sender
h264.h 5KB
sender
H264_STREAM
sender.264 2.94MB
sender.suo 7KB
sender.ncb 6.44MB
debug
sender.exe 10KB
_UpgradeReport_Files
UpgradeReport.xslt 12KB
UpgradeReport_Plus.gif 71B
UpgradeReport.css 3KB
UpgradeReport_Minus.gif 69B
sender.sln 885B
sender
Debug
cl.command.1.tlog 486B
CL.read.1.tlog 13KB
mt.read.1.tlog 804B
link.read.1.tlog 2KB
sender.lastbuildstate 66B
link.write.1.tlog 414B
BuildLog.htm 7KB
mt.dep 67B
CL.write.1.tlog 334B
sender.log 2KB
vc100.pdb 68KB
main.obj 33KB
link.command.1.tlog 1KB
mt.write.1.tlog 290B
mt.command.1.tlog 464B
vc80.idb 123KB
sender.exe.intermediate.manifest 381B
sender.vcproj.PC-200909201114.Administrator.user 1KB
sender.vcxproj.filters 1KB
sender.vcxproj.user 143B
sender.vcxproj 3KB
sender.vcproj 3KB
UpgradeLog.XML 2KB
main.c 11KB
共 69 条
- 1
yangke858
- 粉丝: 1
- 资源: 17
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
前往页