linux+rtmp协议,linux系统RTMPdump(libRTMP) 通过RTMP 发布H264数据

linux系统RTMPdump(libRTMP) 通过RTMP 发布H264数据

linux系统RTMPdump(libRTMP) 通过RTMP 发布H264数据

关于RTMPdump的使用介绍,很多的都是在Windows平台的应用,雷神有做一个系列的分析,但是雷神的也主要是以Windows平台为主。本文主要的工作是将雷神《最简单的基于librtmp的示例:发布H.264(H.264通过RTMP发布)》中的工程移植到linux系统,同时修复一些问题并且添加一部分说明。

在使用该工程之前,应该有搭建好一个RTMP服务器,同时对H264数据格式有一个较好的了解。可以参考:

nginx 搭建rtmp流媒体服务器

H264语法结构及编码原理

整个软件的流程图如下:

crxg2zyridh.JPEG

仔细分析RTMP264_Send 函数

/**

* 将内存中的一段H.264编码的视频数据利用RTMP协议发送到服务器

*

* @param read_buffer 回调函数,当数据不足的时候,系统会自动调用该函数获取输入数据。

*2个参数功能:

*uint8_t *buf:外部数据送至该地址

*int buf_size:外部数据大小

*返回值:成功读取的内存大小

* @成功则返回1 , 失败则返回0

*/

int RTMP264_Send(int (*read_buffer)(unsigned char *buf, int buf_size))

{

int ret;

uint32_t now,last_update;

memset(&metaData,0,sizeof(RTMPMetadata));

memset(m_pFileBuf,0,BUFFER_SIZE);

if((ret=read_buffer(m_pFileBuf,m_nFileBufSize))<0)

{

return FALSE;

}

NaluUnit naluUnit;

// 读取SPS帧

ReadFirstNaluFromBuf(naluUnit,read_buffer);

metaData.nSpsLen = naluUnit.size;

metaData.Sps=NULL;

metaData.Sps=(unsigned char*)malloc(naluUnit.size);

memcpy(metaData.Sps,naluUnit.data,naluUnit.size);

// 读取PPS帧

ReadOneNaluFromBuf(naluUnit,read_buffer);

metaData.nPpsLen = naluUnit.size;

metaData.Pps=NULL;

metaData.Pps=(unsigned char*)malloc(naluUnit.size);

memcpy(metaData.Pps,naluUnit.data,naluUnit.size);

// 解码SPS,获取视频图像宽、高信息

int width = 0,height = 0, fps=0;

h264_decode_sps(metaData.Sps,metaData.nSpsLen,width,height,fps);

//metaData.nWidth = width;

//metaData.nHeight = height;

if(fps)

metaData.nFrameRate = fps;

else

metaData.nFrameRate = 25;

//发送PPS,SPS

//ret=SendVideoSpsPps(metaData.Pps,metaData.nPpsLen,metaData.Sps,metaData.nSpsLen);

//if(ret!=1)

//return FALSE;

unsigned int tick = 0;

unsigned int tick_gap = 1000/metaData.nFrameRate;

//printf(" nFrameRate = %d \n ",metaData.nFrameRate);

ReadOneNaluFromBuf(naluUnit,read_buffer);

int bKeyframe = (naluUnit.type == 0x05) ? TRUE : FALSE;

while(SendH264Packet(naluUnit.data,naluUnit.size,bKeyframe,tick))

{

got_sps_pps:

//if(naluUnit.size==8581)

printf("NALU size:%8d\n",naluUnit.size);

last_update=RTMP_GetTime();

if(!ReadOneNaluFromBuf(naluUnit,read_buffer))

goto end;

if(naluUnit.type == 0x07 || naluUnit.type == 0x08)

goto got_sps_pps;

bKeyframe = (naluUnit.type == 0x05) ? TRUE : FALSE;

tick +=tick_gap;

now=RTMP_GetTime();

//msleep(tick_gap-now+last_update);

//printf("now = %d, last_update = %d, now - last_update = %d \n",now,last_update,now - last_update);

msleep(tick_gap);

}

end:

free(metaData.Sps);

free(metaData.Pps);

return TRUE;

}    在开始循环获取数据之前,先读取h264文件的SPS和PPS。SPS是序列参数集,PPS是图像参数集。在SPS序列参数集中可以解析出图像的宽,高和帧率等信息。而在h264文件中,最开始的两帧数据就是SPS和PPS,这个h264文件只存在一个SPS帧和一个PPS帧。在做RTMP 传输的时候,它需要在每次发送H264的I帧之前,发送SPS序列参数集帧和PPS图像参数集帧。在我们这里的处理方式是,先提取出SPS和PPS帧,然后保存起来,然后每次发送I帧之前都发送一次SPS和PPS帧。SPS帧和PPS帧如下:

a32e51b453b85b615fac3083b2c0de57.png

工程文件如下:

[email protected]:~/test/RTMP/rtmp_push_h264$ tree

.

├── cuc_ieschool.h264

├── include

│   ├── librtmp

│   │   ├── amf.h

│   │   ├── bytes.h

│   │   ├── dhgroups.h

│   │   ├── dh.h

│   │   ├── handshake.h

│   │   ├── http.h

│   │   ├── log.h

│   │   ├── rtmp.h

│   │   └── rtmp_sys.h

│   ├── librtmp_send264.h

│   └── sps_decode.h

├── lib

│   ├── librtmp.a

│   ├── librtmp.so

│   └── librtmp.so.0

├── librtmp_send264.cpp

├── Makefile

├── simplest_librtmp_send264.cpp

└── src

完整的工程下载地址:RTMPdump(libRTMP) 通过RTMP 发布H264数据

linux系统RTMPdump(libRTMP) 通过RTMP 发布H264数据相关教程

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值