//在網上找到的demo都是linux的,我將他改爲vc的工程,推流成功
#include "stdio.h"
#include "string.h"
#include "rtp.h"
#include <windows.h>
//Windows套接字所需的頭文件
#include <WINSOCK.H>
//Windows套接字接口的庫文件
#pragma comment(lib, "WSOCK32.LIB")
//程序使用的WinSock主版本
#define SOCK_VER 2
#define FramePreSec 25
int main(int argc, char* argv[])
{
SOCKET sock;
char *sendbuf;
RTP_FIXED_HEADER *pRtpHeader;
int ret, addr, time_cnt = 0x00000000, seq_num = 0, sendcnt = 0;
S_NULU nalu;
FILE *fp;
sock = InitUDP();
if (sock==0)
{
printf("socket err");
return 1;
}
nalu.buf = new char[MAX_NALU_SIZE];
sendbuf = new char[sizeof(RTP_FIXED_HEADER) +2+ MAX_RTP_PKT_LENGTH]; //1 is 用於分包時候計算的數據
pRtpHeader = (RTP_FIXED_HEADER *)sendbuf;
nalu.max_size = MAX_NALU_SIZE;
fp = fopen("test.h264", "rb");
pRtpHeader = (RTP_FIXED_HEADER*)&sendbuf[0];
//設置RTP HEADER,
//4 位。表示跟在 RTP 固定包頭後面CSRC 的數目,對於本文所要實現的基本的流媒體服務器來說,沒有用到混合器,該位也設爲 0x0
pRtpHeader->csrc_len = 0;
//rtp_hdr->extension=0;
//rtp_hdr->padding=0;
pRtpHeader->payload = H264; //負載類型號, h264
pRtpHeader->version = 2; //版本號,此版本固定爲2
pRtpHeader->marker = 0; //標誌位,由具體協議規定其值。
pRtpHeader->ssrc = htonl(0xA53D8F5D); //隨機指定爲10,並且在本RTP會話中全局唯一 bytes 8-11
do{
//if (feof(fp)) fseek(fp, 0, SEEK_SET);
//addr = ftell(fp);
//printf("file addr:%06X ", addr);
ret = GetAnnexbNALU(&nalu, fp);
if (ret == 0)
{
printf("nalutype:%02X,len:%d\r\n", nalu.buf[0], nalu.len);
}
//獲取幀成功
//設定 rtp header
if (nalu.len <= MAX_RTP_PKT_LENGTH)
{
//設置rtp M 位,1 位。如果當前 NALU爲一個接入單元最後的那個NALU,那麼將M位置 1;或者當前RTP 數據包爲一個NALU 的最後的那個分片時(NALU 的分片在後面講述),M位置 1。其餘情況下M 位保持爲 0
pRtpHeader->marker = 1;
if (nalu.nal_unit_type < 6 || nalu.nal_unit_type>8)
{
time_cnt += 90000 / FramePreSec; //6-8不是顯示數據幀
}
pRtpHeader->timestamp = htonl(time_cnt);
pRtpHeader->seq_no = htons(seq_num++); //序列號,每發送一個RTP包增1
//sendbuf[12]和nalu.buf[0] 是 NALU_HEADER ,數據一樣
memcpy(sendbuf + sizeof(RTP_FIXED_HEADER), nalu.buf, nalu.len);
sendcnt+=UdpSendData(sendbuf, nalu.len + sizeof(RTP_FIXED_HEADER), sock);
}
else
{
int cnt= nalu.len-1,len;
char *pGetBuf=nalu.buf+1;
//設置rtp M 位,1 位。如果當前 NALU爲一個接入單元最後的那個NALU,那麼將M位置 1;或者當前RTP 數據包爲一個NALU 的最後的那個分片時(NALU 的分片在後面講述),M位置 1。其餘情況下M 位保持爲 0
pRtpHeader->marker = 0;
time_cnt += 90000 / FramePreSec; pRtpHeader->timestamp = htonl(time_cnt);
sendbuf[12] = (nalu.buf[0] & 0xE0) | 0x1C; //將sendbuf[12]的地址賦給fu_ind,之後對fu_ind的寫入就將寫入sendbuf中;
sendbuf[13] = 0x80 | (nalu.buf[0]&0x1F); //0x80 組包開始標識begin flag
do{
if (cnt >= 1400) len = 1400;
else len = cnt;
memcpy(sendbuf + 14, pGetBuf, len);
pGetBuf += len;
cnt -= len;
if (cnt <= 0)
{
pRtpHeader->marker = 1;
sendbuf[13] |= 0x40; //組包結束標誌
}
pRtpHeader->seq_no = htons(seq_num++); //序列號,每發送一個RTP包增1
sendcnt += UdpSendData(sendbuf, len + sizeof(RTP_FIXED_HEADER) + 2, sock);
sendbuf[13] &= 0x1F;
//printf(".");
} while (cnt);
printf("wait:%d\r\n", seq_num); //getchar();
}
if (nalu.nal_unit_type < 6 || nalu.nal_unit_type>8) Sleep(1000 / FramePreSec);
} while (ret == 0);
printf("send:%d\r\n", sendcnt);
return 0;
}