rtp发送h264 vlc进行播放

//在网上找到的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;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值